{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lesson 15 - Pandas Time Series\n",
    "\n",
    "### Readings\n",
    "\n",
    "* McKinney: [Chapter 11. Time Series](http://proquest.safaribooksonline.com/book/programming/python/9781491957653/time-series/timeseries_html)\n",
    "\n",
    "### Table of Contents\n",
    "\n",
    "* [Examples](#examples)\n",
    "* [Timeseries classes](#classes)\n",
    "* [Timestamps vs. Periods (time spans)](#timestamps-vs-periods)\n",
    "* [Converting to Timestamps](#coverting-to-timestamps)\n",
    "* [Generating ranges of timestamps](#ranges-of-timestamps)\n",
    "* [DatetimeIndex](#datetimeindex)\n",
    "* [DateOffset objects](#dateoffset-objects)\n",
    "* [Time series-related instance methods](#instance-methods)\n",
    "* [Time span representation](#time-spans)\n",
    "* [Time zone handling](#time-zones)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Adapted from Pandas documentation (esoteric/financial applications left out).*\n",
    "\n",
    "In working with time series data, we will frequently seek to:\n",
    "\n",
    "* generate sequences of fixed-frequency dates and time spans\n",
    "* conform or convert time series to a particular frequency\n",
    "* compute “relative” dates based on various non-standard time increments (e.g. 5 business days before the last business day of the year), or “roll” dates forward or backward\n",
    "\n",
    "Pandas provides a relatively compact and self-contained set of tools for performing the above tasks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# modules used in this tutorial\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import pytz\n",
    "import dateutil"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# set max row and random seed\n",
    "pd.set_option(\"display.max_rows\", 10)\n",
    "np.random.seed(12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"examples\"></a>\n",
    "\n",
    "## Examples\n",
    "\n",
    "Create a range of dates:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "rng = pd.date_range('1/1/2011', periods=72, freq='H')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-01 00:00:00', '2011-01-01 01:00:00',\n",
       "               '2011-01-01 02:00:00', '2011-01-01 03:00:00',\n",
       "               '2011-01-01 04:00:00'],\n",
       "              dtype='datetime64[ns]', freq='H')"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "72"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(rng)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Index Pandas objects with dates:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = pd.Series(np.random.randn(len(rng)), index=rng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-01 00:00:00    0.472986\n",
       "2011-01-01 01:00:00   -0.681426\n",
       "2011-01-01 02:00:00    0.242439\n",
       "2011-01-01 03:00:00   -1.700736\n",
       "2011-01-01 04:00:00    0.753143\n",
       "Freq: H, dtype: float64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Change frequency and fill gaps:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# to 45 minute frequency and forward fill\n",
    "converted = ts.asfreq('45Min', method='pad')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-01 00:00:00    0.472986\n",
       "2011-01-01 00:45:00    0.472986\n",
       "2011-01-01 01:30:00   -0.681426\n",
       "2011-01-01 02:15:00    0.242439\n",
       "2011-01-01 03:00:00   -1.700736\n",
       "Freq: 45T, dtype: float64"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "converted.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Frequency conversion and resampling of a time series:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-01    0.106866\n",
       "2011-01-02   -0.449748\n",
       "2011-01-03    0.006654\n",
       "Freq: D, dtype: float64"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.resample('D').mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-01 00:00:00    0.472986\n",
       "2011-01-01 01:00:00   -0.681426\n",
       "2011-01-01 02:00:00    0.242439\n",
       "2011-01-01 03:00:00   -1.700736\n",
       "2011-01-01 04:00:00    0.753143\n",
       "                         ...   \n",
       "2011-01-03 19:00:00    1.029211\n",
       "2011-01-03 20:00:00   -1.166259\n",
       "2011-01-03 21:00:00   -1.009562\n",
       "2011-01-03 22:00:00   -0.105268\n",
       "2011-01-03 23:00:00    0.512022\n",
       "Length: 72, dtype: float64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.resample('T').mean().dropna()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Find difference between dates:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timedelta('322 days 00:00:00')"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('11/19/18') - pd.Timestamp('1/1/18')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "322"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period('11/19/18') - pd.Period('1/1/18')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"classes\"></a>\n",
    "\n",
    "## Timeseries classes\n",
    "\n",
    "The following table shows the type of time-related classes pandas can handle and how to create them:\n",
    "\n",
    "Class | Remarks | How to create\n",
    "------|---------|--------------\n",
    "`Timestamp` | Represents a single time stamp | `to_datetime`, `Timestamp`\n",
    "`DatetimeIndex` | Index (~array) of `Timestamp` | `to_datetime`, `date_range`, `DatetimeIndex`\n",
    "`Period` | Represents a single time span | `Period`\n",
    "`PeriodIndex` | Index (~array) of `Period` | `period_range`, `PeriodIndex`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"timestamps-vs-periods\"></a>\n",
    "\n",
    "## Timestamps vs. Periods (time spans)\n",
    "\n",
    "Time-stamped data is the most basic type of timeseries data that associates values with points in time. For pandas objects it means using the points in time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "datetime.datetime(2012, 5, 1, 0, 0)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.datetime(2012, 5, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-05-01 00:00:00')"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp(pd.datetime(2012, 5, 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-05-01 00:00:00')"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('2012-05-01')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, in many cases it is more natural to associate things like change variables with a time span instead. The span represented by Period can be specified explicitly, or inferred from datetime string format.\n",
    "\n",
    "For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2011-01', 'M')"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period('2011-01')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2012-05-01', 'D')"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period('2012-05', freq='D')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Timestamp and Period can be the index. Lists of Timestamp and Period are automatically coerced to DatetimeIndex and PeriodIndex respectively."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "dates = [pd.Timestamp('2012-05-01'), pd.Timestamp('2012-05-02'), pd.Timestamp('2012-05-03')]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = pd.Series(np.random.randn(3), dates)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-05-01    1.407728\n",
       "2012-05-02   -1.687696\n",
       "2012-05-03    1.471234\n",
       "dtype: float64"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-05-01', '2012-05-02', '2012-05-03'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "pandas.core.indexes.datetimes.DatetimeIndex"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(ts.index)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "periods = [pd.Period('2012-01'), pd.Period('2012-02'), pd.Period('2012-03')]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = pd.Series(np.random.randn(3), periods)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-01    1.636463\n",
       "2012-02   -0.461395\n",
       "2012-03   -0.201362\n",
       "Freq: M, dtype: float64"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2012-01', '2012-02', '2012-03'], dtype='period[M]', freq='M')"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "pandas.core.indexes.period.PeriodIndex"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(ts.index)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pandas allows you to capture both representations and convert between them. Under the hood, Pandas represents timestamps using instances of Timestamp and sequences of timestamps using instances of DatetimeIndex. For regular time spans, Pandas uses Period objects for scalar values and PeriodIndex for sequences of spans."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"coverting-to-timestamps\"></a>\n",
    "\n",
    "## Converting to Timestamps\n",
    "\n",
    "To convert a Series or list-like object of date-like objects e.g. strings, epochs, or a mixture, you can use the to_datetime function. When passed a Series, this returns a Series (with the same index), while a list-like is converted to a DatetimeIndex:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2009-07-31\n",
       "1   2010-01-10\n",
       "2          NaT\n",
       "dtype: datetime64[ns]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(pd.Series(['Jul 31, 2009', '2010-01-10', None]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2005-11-23', '2010-12-31'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(['2005/11/23', '2010.12.31'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you use dates which start with the day first (i.e. European style), you can pass the dayfirst flag:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-04-01'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(['04-01-2012']) # default behavior is dayfirst=False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-04-01'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(['04-01-2012'], dayfirst=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-01-04'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(['04-01-2012'], dayfirst=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Warning:** If a date can’t be parsed with the day being first it will be parsed as if dayfirst were False:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-04-13'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(['04-13-2012'], dayfirst=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Warning:** Even with a list of dates that are clearly European (day first), each date is processed separately. You must specify `dayfirst=True` (or a format argument) to get the desired behaviour:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2018-10-01', '2018-11-01', '2018-12-01', '2018-01-13',\n",
       "               '2018-01-14'],\n",
       "              dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(['10/1/18', '11/1/18', '12/1/18', '13/1/18', '14/1/18'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2018-01-10', '2018-01-11', '2018-01-12', '2018-01-13',\n",
       "               '2018-01-14'],\n",
       "              dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(['10/1/18', '11/1/18', '12/1/18', '13/1/18', '14/1/18'], dayfirst=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note:** Specifying a format argument will potentially speed up the conversion considerably and on versions later than 0.13.0 explicitly specifying a format string of ‘%Y%m%d’ takes a faster path still.\n",
    "\n",
    "If you pass a single string to to_datetime, it returns single Timestamp. Also, Timestamp can accept the string input. Note that Timestamp doesn’t accept string parsing option like dayfirst or format: use to_datetime if these are required.\n",
    "\n",
    "The first option below would work with a list of dates, but the second would not."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2010-12-11 00:00:00')"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime('11/12/2010', format='%d/%m/%Y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2010-11-12 00:00:00')"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime('11/12/2010', format='%m/%d/%Y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2010-11-12 00:00:00')"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime('11/12/2010')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2010-11-12 00:00:00')"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('2010-11-12')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Invalid data\n",
    "\n",
    "In version 0.17.0, the default for to_datetime is now errors='raise', rather than errors='ignore'. This means that invalid parsing will raise rather that return the original input as in previous versions.\n",
    "\n",
    "Pass errors='coerce' to convert invalid data to NaT (not a time):"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "# this is the default, raise when unparseable -- convert cell type to Code to see error\n",
    "pd.to_datetime(['2009/07/31', 'asd'], errors='raise')"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "# again, default is to generate an error\n",
    "pd.to_datetime(['2009/07/31', 'asd'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['2009/07/31', 'asd'], dtype=object)"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# don't convert anything and return the original input when unparseable\n",
    "pd.to_datetime(['2009/07/31', 'asd'], errors='ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2009-07-31', 'NaT'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# return NaT for input when unparseable\n",
    "pd.to_datetime(['2009/07/31', 'asd'], errors='coerce')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Epoch timestamps\n",
    "\n",
    "It’s also possible to convert integer or float epoch times. The default unit for these is nanoseconds (since these are how Timestamps are stored). However, often epochs are stored in another unit which can be specified:\n",
    "\n",
    "Typical epoch stored units (nanoseconds):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('1970-01-01 00:00:00')"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('1970-01-01 00:00:00.000000001')"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('1970-01-01 00:00:03')"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime(3e9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-10-08 18:15:05', '2012-10-09 18:15:05',\n",
       "               '2012-10-10 18:15:05', '2012-10-11 18:15:05',\n",
       "               '2012-10-12 18:15:05'],\n",
       "              dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime([1349720105, 1349806505, 1349892905, 1349979305, 1350065705], unit='s')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-10-08 18:15:05.100000', '2012-10-08 18:15:05.200000',\n",
       "               '2012-10-08 18:15:05.300000', '2012-10-08 18:15:05.400000',\n",
       "               '2012-10-08 18:15:05.500000'],\n",
       "              dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.to_datetime([1349720105100, 1349720105200, 1349720105300, 1349720105400, 1349720105500 ], unit='ms')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note:** Epoch times will be rounded to the nearest nanosecond."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"ranges-of-timestamps\"></a>\n",
    "\n",
    "## Generating ranges of timestamps\n",
    "\n",
    "To generate an index with time stamps, you can use either the DatetimeIndex or Index constructor and pass in a list of datetime objects"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The slow way"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "dates = [pd.datetime(2012, 5, 1), pd.datetime(2012, 5, 2), pd.datetime(2012, 5, 3)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "index = pd.DatetimeIndex(dates)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-05-01', '2012-05-02', '2012-05-03'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "index # Note the frequency information"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "index = pd.Index(dates)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-05-01', '2012-05-02', '2012-05-03'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "index # Automatically converted to DatetimeIndex"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The quick way - date_range by periods or start-end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Practically, this becomes very cumbersome because we often need a very long index with a large number of timestamps. \n",
    "\n",
    "If we need timestamps on a regular frequency, we can use the pandas function date_range to create timestamp indexes. (A similar function and bdate_range does the same thing for business days; the 'b' stands for 'business'.)\n",
    "\n",
    "Information needed to specify date ranges:\n",
    "\n",
    "* start, number of periods, AND frequency\n",
    "* start, end, AND frequency\n",
    "\n",
    "Frequency defaults to 'D' for date_range and 'B' for bdate_range."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2018-03-31', '2018-04-30', '2018-05-31', '2018-06-30',\n",
       "               '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31',\n",
       "               '2018-11-30', '2018-12-31',\n",
       "               ...\n",
       "               '2100-09-30', '2100-10-31', '2100-11-30', '2100-12-31',\n",
       "               '2101-01-31', '2101-02-28', '2101-03-31', '2101-04-30',\n",
       "               '2101-05-31', '2101-06-30'],\n",
       "              dtype='datetime64[ns]', length=1000, freq='M')"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# freq='M' uses last day of month by default\n",
    "index = pd.date_range('2018-3-1', periods=1000, freq='M')\n",
    "index "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2018-03-01', '2018-03-02', '2018-03-05', '2018-03-06',\n",
       "               '2018-03-07', '2018-03-08', '2018-03-09', '2018-03-12',\n",
       "               '2018-03-13', '2018-03-14',\n",
       "               ...\n",
       "               '2021-12-16', '2021-12-17', '2021-12-20', '2021-12-21',\n",
       "               '2021-12-22', '2021-12-23', '2021-12-24', '2021-12-27',\n",
       "               '2021-12-28', '2021-12-29'],\n",
       "              dtype='datetime64[ns]', length=1000, freq='B')"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# freq='B' is business days\n",
    "index = pd.date_range('2018-3-1', periods=1000, freq='B')\n",
    "index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2018-03-01', '2018-03-02', '2018-03-03', '2018-03-04',\n",
       "               '2018-03-05', '2018-03-06', '2018-03-07', '2018-03-08',\n",
       "               '2018-03-09', '2018-03-10',\n",
       "               ...\n",
       "               '2020-11-15', '2020-11-16', '2020-11-17', '2020-11-18',\n",
       "               '2020-11-19', '2020-11-20', '2020-11-21', '2020-11-22',\n",
       "               '2020-11-23', '2020-11-24'],\n",
       "              dtype='datetime64[ns]', length=1000, freq='D')"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# default is freq='D' for date_range\n",
    "index = pd.date_range('2018-3-1', periods=1000)\n",
    "index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2018-03-01', '2018-03-02', '2018-03-05', '2018-03-06',\n",
       "               '2018-03-07', '2018-03-08', '2018-03-09', '2018-03-12',\n",
       "               '2018-03-13', '2018-03-14',\n",
       "               ...\n",
       "               '2021-12-16', '2021-12-17', '2021-12-20', '2021-12-21',\n",
       "               '2021-12-22', '2021-12-23', '2021-12-24', '2021-12-27',\n",
       "               '2021-12-28', '2021-12-29'],\n",
       "              dtype='datetime64[ns]', length=1000, freq='B')"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# default is freq='B' for bdate_range\n",
    "index = pd.bdate_range('2018-3-1', periods=1000)\n",
    "index"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Commonly used of offset aliases\n",
    "\n",
    "Alias | Description\n",
    "------|------------\n",
    "D | day frequency\n",
    "B | business day frequency\n",
    "W | weekly frequency\n",
    "BW | business week end frequency\n",
    "M | month end frequency\n",
    "BM | business month end frequency\n",
    "MS | month start frequency\n",
    "A | year end frequency\n",
    "BA | business year end frequency\n",
    "AS | year start frequency\n",
    "H | hourly frequency\n",
    "T, min | minutely frequency\n",
    "S | secondly frequency\n",
    "L, ms | milliseonds\n",
    "U, us | microseconds\n",
    "N | nanoseconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "t1 = pd.datetime(2011, 1, 1)\n",
    "t2 = pd.datetime(2012, 1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04',\n",
       "               '2011-01-05', '2011-01-06', '2011-01-07', '2011-01-08',\n",
       "               '2011-01-09', '2011-01-10',\n",
       "               ...\n",
       "               '2011-12-23', '2011-12-24', '2011-12-25', '2011-12-26',\n",
       "               '2011-12-27', '2011-12-28', '2011-12-29', '2011-12-30',\n",
       "               '2011-12-31', '2012-01-01'],\n",
       "              dtype='datetime64[ns]', length=366, freq='D')"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng = pd.date_range(t1, t2, freq='D')\n",
    "rng"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-02', '2011-01-09', '2011-01-16', '2011-01-23',\n",
       "               '2011-01-30', '2011-02-06', '2011-02-13', '2011-02-20',\n",
       "               '2011-02-27', '2011-03-06', '2011-03-13', '2011-03-20',\n",
       "               '2011-03-27', '2011-04-03', '2011-04-10', '2011-04-17',\n",
       "               '2011-04-24', '2011-05-01', '2011-05-08', '2011-05-15',\n",
       "               '2011-05-22', '2011-05-29', '2011-06-05', '2011-06-12',\n",
       "               '2011-06-19', '2011-06-26', '2011-07-03', '2011-07-10',\n",
       "               '2011-07-17', '2011-07-24', '2011-07-31', '2011-08-07',\n",
       "               '2011-08-14', '2011-08-21', '2011-08-28', '2011-09-04',\n",
       "               '2011-09-11', '2011-09-18', '2011-09-25', '2011-10-02',\n",
       "               '2011-10-09', '2011-10-16', '2011-10-23', '2011-10-30',\n",
       "               '2011-11-06', '2011-11-13', '2011-11-20', '2011-11-27',\n",
       "               '2011-12-04', '2011-12-11', '2011-12-18', '2011-12-25',\n",
       "               '2012-01-01'],\n",
       "              dtype='datetime64[ns]', freq='W-SUN')"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(t1, t2, freq='W-SUN')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-03', '2011-01-04', '2011-01-05', '2011-01-06',\n",
       "               '2011-01-07', '2011-01-10', '2011-01-11', '2011-01-12',\n",
       "               '2011-01-13', '2011-01-14',\n",
       "               ...\n",
       "               '2011-12-19', '2011-12-20', '2011-12-21', '2011-12-22',\n",
       "               '2011-12-23', '2011-12-26', '2011-12-27', '2011-12-28',\n",
       "               '2011-12-29', '2011-12-30'],\n",
       "              dtype='datetime64[ns]', length=260, freq='B')"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(t1, t2, freq='B')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-31', '2011-02-28', '2011-03-31', '2011-04-29',\n",
       "               '2011-05-31', '2011-06-30', '2011-07-29', '2011-08-31',\n",
       "               '2011-09-30', '2011-10-31', '2011-11-30', '2011-12-30'],\n",
       "              dtype='datetime64[ns]', freq='BM')"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(t1, t2, freq='BM')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-12-05', '2011-12-06', '2011-12-07', '2011-12-08',\n",
       "               '2011-12-09', '2011-12-12', '2011-12-13', '2011-12-14',\n",
       "               '2011-12-15', '2011-12-16', '2011-12-19', '2011-12-20',\n",
       "               '2011-12-21', '2011-12-22', '2011-12-23', '2011-12-26',\n",
       "               '2011-12-27', '2011-12-28', '2011-12-29', '2011-12-30'],\n",
       "              dtype='datetime64[ns]', freq='B')"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.bdate_range(end=t2, periods=20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-03', '2011-01-04', '2011-01-05', '2011-01-06',\n",
       "               '2011-01-07', '2011-01-10', '2011-01-11', '2011-01-12',\n",
       "               '2011-01-13', '2011-01-14', '2011-01-17', '2011-01-18',\n",
       "               '2011-01-19', '2011-01-20', '2011-01-21', '2011-01-24',\n",
       "               '2011-01-25', '2011-01-26', '2011-01-27', '2011-01-28'],\n",
       "              dtype='datetime64[ns]', freq='B')"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.bdate_range(start=t1, periods=20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"datetimeindex\"></a>\n",
    "\n",
    "## DatetimeIndex\n",
    "\n",
    "One of the main uses for DatetimeIndex is as an index for Pandas objects. The DatetimeIndex class contains many timeseries related optimizations:\n",
    "\n",
    "* A large range of dates for various offsets are pre-computed and cached under the hood in order to make generating subsequent date ranges very fast (just have to grab a slice)\n",
    "* Fast shifting using the shift and tshift method on pandas objects\n",
    "* Unioning of overlapping DatetimeIndex objects with the same frequency is very fast (important for fast data alignment)\n",
    "* Quick access to date fields via properties such as year, month, etc.\n",
    "* Regularization functions like snap and very fast asof logic\n",
    "\n",
    "DatetimeIndex objects has all the basic functionality of regular Index objects and a smorgasbord of advanced timeseries-specific methods for easy frequency processing.\n",
    "\n",
    "See also documentation for *Reindexing methods*.\n",
    "\n",
    "**Note:** While Pandas does not force you to have a sorted date index, some of these methods may have unexpected or incorrect behavior if the dates are unsorted. So please be careful.\n",
    "\n",
    "DatetimeIndex can be used like a regular index and offers all of its intelligent functionality like selection, slicing, etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "start = pd.datetime(2011, 1, 1)\n",
    "end = pd.datetime(2012, 1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng = pd.date_range(start, end, freq='BM')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = pd.Series(np.random.randn(len(rng)), index=rng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-31', '2011-02-28', '2011-03-31', '2011-04-29',\n",
       "               '2011-05-31', '2011-06-30', '2011-07-29', '2011-08-31',\n",
       "               '2011-09-30', '2011-10-31', '2011-11-30', '2011-12-30'],\n",
       "              dtype='datetime64[ns]', freq='BM')"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-31', '2011-02-28', '2011-03-31', '2011-04-29',\n",
       "               '2011-05-31'],\n",
       "              dtype='datetime64[ns]', freq='BM')"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts[:5].index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-31', '2011-03-31', '2011-05-31', '2011-07-29',\n",
       "               '2011-09-30', '2011-11-30'],\n",
       "              dtype='datetime64[ns]', freq='2BM')"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts[::2].index"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Slicing revisited"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In Pandas, **label-based slicing is inclusive**, whereas **index-based slicing is NOT inclusive** (like index-based slicing in Python generally)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    0.0\n",
       "b    0.1\n",
       "c    0.2\n",
       "dtype: float64"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = pd.Series([0.0, 0.1, 0.2], index=['a', 'b', 'c'])\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    0.0\n",
       "b    0.1\n",
       "dtype: float64"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[0:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    0.0\n",
       "b    0.1\n",
       "c    0.2\n",
       "dtype: float64"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x['a':'c']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "DatetimeIndex-based slicing is effectively label-based, so it is inclusive. It will not generate any dates outside of those dates if specified."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DatetimeIndex partial string 'smart' indexing\n",
    "\n",
    "You can pass in dates and strings that parse to dates as indexing parameters:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-31   -0.571817\n",
       "2011-02-28   -0.603299\n",
       "2011-03-31   -1.339389\n",
       "2011-04-29   -1.689653\n",
       "2011-05-31   -0.199327\n",
       "                ...   \n",
       "2011-08-31   -1.001002\n",
       "2011-09-30   -2.091691\n",
       "2011-10-31    0.146560\n",
       "2011-11-30   -0.466351\n",
       "2011-12-30    0.356223\n",
       "Freq: BM, Length: 12, dtype: float64"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-0.5718167302823739"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts['1/31/2011']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-12-30    0.356223\n",
       "Freq: BM, dtype: float64"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts[pd.datetime(2011, 12, 25):]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-10-31    0.146560\n",
       "2011-11-30   -0.466351\n",
       "2011-12-30    0.356223\n",
       "Freq: BM, dtype: float64"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts['10/1/2011':'12/31/2011']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To provide convenience for accessing longer time series, you can also pass in the year or year and month as strings:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-31   -0.571817\n",
       "2011-02-28   -0.603299\n",
       "2011-03-31   -1.339389\n",
       "2011-04-29   -1.689653\n",
       "2011-05-31   -0.199327\n",
       "                ...   \n",
       "2011-08-31   -1.001002\n",
       "2011-09-30   -2.091691\n",
       "2011-10-31    0.146560\n",
       "2011-11-30   -0.466351\n",
       "2011-12-30    0.356223\n",
       "Freq: BM, Length: 12, dtype: float64"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts['2011']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-06-30    0.257773\n",
       "Freq: BM, dtype: float64"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts['2011-6']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we only want timestamps that match a certain day of the month (e.g., 31):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2011-10-31 00:00:00')"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = pd.Timestamp('10/31/2011')\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "31"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.day"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-31   -0.571817\n",
       "2011-03-31   -1.339389\n",
       "2011-05-31   -0.199327\n",
       "2011-08-31   -1.001002\n",
       "2011-10-31    0.146560\n",
       "dtype: float64"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts[[(x.day == 31) for x in ts.index]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-31   -0.571817\n",
       "2011-03-31   -1.339389\n",
       "2011-05-31   -0.199327\n",
       "2011-08-31   -1.001002\n",
       "2011-10-31    0.146560\n",
       "dtype: float64"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts[ts.index.day == 31]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This type of slicing will work on a DataFrame with a DateTimeIndex as well. Since the partial string selection is a form of label slicing, the endpoints will be included. This would include matching times on an included date. Here’s an example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [],
   "source": [
    "dft = pd.DataFrame(np.random.randn(100000,1), columns=['A'], \n",
    "                   index=pd.date_range('20130101', periods=100000, freq='T'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100000, 1)"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:00:00</th>\n",
       "      <td>-0.397880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:01:00</th>\n",
       "      <td>-1.259224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:02:00</th>\n",
       "      <td>-0.688879</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:03:00</th>\n",
       "      <td>0.802630</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:04:00</th>\n",
       "      <td>0.272391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:35:00</th>\n",
       "      <td>-0.454453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:36:00</th>\n",
       "      <td>-0.448193</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:37:00</th>\n",
       "      <td>-0.393987</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:38:00</th>\n",
       "      <td>1.175407</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:39:00</th>\n",
       "      <td>0.020738</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>100000 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                            A\n",
       "2013-01-01 00:00:00 -0.397880\n",
       "2013-01-01 00:01:00 -1.259224\n",
       "2013-01-01 00:02:00 -0.688879\n",
       "2013-01-01 00:03:00  0.802630\n",
       "2013-01-01 00:04:00  0.272391\n",
       "...                       ...\n",
       "2013-03-11 10:35:00 -0.454453\n",
       "2013-03-11 10:36:00 -0.448193\n",
       "2013-03-11 10:37:00 -0.393987\n",
       "2013-03-11 10:38:00  1.175407\n",
       "2013-03-11 10:39:00  0.020738\n",
       "\n",
       "[100000 rows x 1 columns]"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:00:00</th>\n",
       "      <td>-0.397880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:01:00</th>\n",
       "      <td>-1.259224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:02:00</th>\n",
       "      <td>-0.688879</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:03:00</th>\n",
       "      <td>0.802630</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:04:00</th>\n",
       "      <td>0.272391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:35:00</th>\n",
       "      <td>-0.454453</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:36:00</th>\n",
       "      <td>-0.448193</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:37:00</th>\n",
       "      <td>-0.393987</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:38:00</th>\n",
       "      <td>1.175407</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-03-11 10:39:00</th>\n",
       "      <td>0.020738</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>100000 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                            A\n",
       "2013-01-01 00:00:00 -0.397880\n",
       "2013-01-01 00:01:00 -1.259224\n",
       "2013-01-01 00:02:00 -0.688879\n",
       "2013-01-01 00:03:00  0.802630\n",
       "2013-01-01 00:04:00  0.272391\n",
       "...                       ...\n",
       "2013-03-11 10:35:00 -0.454453\n",
       "2013-03-11 10:36:00 -0.448193\n",
       "2013-03-11 10:37:00 -0.393987\n",
       "2013-03-11 10:38:00  1.175407\n",
       "2013-03-11 10:39:00  0.020738\n",
       "\n",
       "[100000 rows x 1 columns]"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft['2013']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This starts on the very first time in the month, and includes the last date & time for the month:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:00:00</th>\n",
       "      <td>-0.397880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:01:00</th>\n",
       "      <td>-1.259224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:02:00</th>\n",
       "      <td>-0.688879</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:03:00</th>\n",
       "      <td>0.802630</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:04:00</th>\n",
       "      <td>0.272391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:55:00</th>\n",
       "      <td>-0.722004</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:56:00</th>\n",
       "      <td>-0.177387</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:57:00</th>\n",
       "      <td>-0.783767</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:58:00</th>\n",
       "      <td>1.515255</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:59:00</th>\n",
       "      <td>0.501890</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>84960 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                            A\n",
       "2013-01-01 00:00:00 -0.397880\n",
       "2013-01-01 00:01:00 -1.259224\n",
       "2013-01-01 00:02:00 -0.688879\n",
       "2013-01-01 00:03:00  0.802630\n",
       "2013-01-01 00:04:00  0.272391\n",
       "...                       ...\n",
       "2013-02-28 23:55:00 -0.722004\n",
       "2013-02-28 23:56:00 -0.177387\n",
       "2013-02-28 23:57:00 -0.783767\n",
       "2013-02-28 23:58:00  1.515255\n",
       "2013-02-28 23:59:00  0.501890\n",
       "\n",
       "[84960 rows x 1 columns]"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft['2013-1':'2013-2']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This specifies a stop time that includes all of the times on the last day:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:00:00</th>\n",
       "      <td>-0.397880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:01:00</th>\n",
       "      <td>-1.259224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:02:00</th>\n",
       "      <td>-0.688879</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:03:00</th>\n",
       "      <td>0.802630</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:04:00</th>\n",
       "      <td>0.272391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:55:00</th>\n",
       "      <td>-0.722004</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:56:00</th>\n",
       "      <td>-0.177387</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:57:00</th>\n",
       "      <td>-0.783767</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:58:00</th>\n",
       "      <td>1.515255</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 23:59:00</th>\n",
       "      <td>0.501890</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>84960 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                            A\n",
       "2013-01-01 00:00:00 -0.397880\n",
       "2013-01-01 00:01:00 -1.259224\n",
       "2013-01-01 00:02:00 -0.688879\n",
       "2013-01-01 00:03:00  0.802630\n",
       "2013-01-01 00:04:00  0.272391\n",
       "...                       ...\n",
       "2013-02-28 23:55:00 -0.722004\n",
       "2013-02-28 23:56:00 -0.177387\n",
       "2013-02-28 23:57:00 -0.783767\n",
       "2013-02-28 23:58:00  1.515255\n",
       "2013-02-28 23:59:00  0.501890\n",
       "\n",
       "[84960 rows x 1 columns]"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft['2013-1':'2013-2-28']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This specifies an exact stop time (and is not the same as the above):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:00:00</th>\n",
       "      <td>-0.397880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:01:00</th>\n",
       "      <td>-1.259224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:02:00</th>\n",
       "      <td>-0.688879</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:03:00</th>\n",
       "      <td>0.802630</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:04:00</th>\n",
       "      <td>0.272391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-27 23:56:00</th>\n",
       "      <td>0.702629</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-27 23:57:00</th>\n",
       "      <td>-1.015303</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-27 23:58:00</th>\n",
       "      <td>-0.433161</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-27 23:59:00</th>\n",
       "      <td>-0.010935</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 00:00:00</th>\n",
       "      <td>0.466138</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>83521 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                            A\n",
       "2013-01-01 00:00:00 -0.397880\n",
       "2013-01-01 00:01:00 -1.259224\n",
       "2013-01-01 00:02:00 -0.688879\n",
       "2013-01-01 00:03:00  0.802630\n",
       "2013-01-01 00:04:00  0.272391\n",
       "...                       ...\n",
       "2013-02-27 23:56:00  0.702629\n",
       "2013-02-27 23:57:00 -1.015303\n",
       "2013-02-27 23:58:00 -0.433161\n",
       "2013-02-27 23:59:00 -0.010935\n",
       "2013-02-28 00:00:00  0.466138\n",
       "\n",
       "[83521 rows x 1 columns]"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft['2013-1':'2013-2-28 00:00:00']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are stopping on the included end-point as it is part of the index:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-15 00:00:00</th>\n",
       "      <td>0.379735</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 00:01:00</th>\n",
       "      <td>-0.898181</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 00:02:00</th>\n",
       "      <td>-0.310935</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 00:03:00</th>\n",
       "      <td>1.069495</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 00:04:00</th>\n",
       "      <td>1.050672</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 12:26:00</th>\n",
       "      <td>0.534819</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 12:27:00</th>\n",
       "      <td>0.648445</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 12:28:00</th>\n",
       "      <td>0.505925</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 12:29:00</th>\n",
       "      <td>-0.969934</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-15 12:30:00</th>\n",
       "      <td>-3.286898</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>751 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                            A\n",
       "2013-01-15 00:00:00  0.379735\n",
       "2013-01-15 00:01:00 -0.898181\n",
       "2013-01-15 00:02:00 -0.310935\n",
       "2013-01-15 00:03:00  1.069495\n",
       "2013-01-15 00:04:00  1.050672\n",
       "...                       ...\n",
       "2013-01-15 12:26:00  0.534819\n",
       "2013-01-15 12:27:00  0.648445\n",
       "2013-01-15 12:28:00  0.505925\n",
       "2013-01-15 12:29:00 -0.969934\n",
       "2013-01-15 12:30:00 -3.286898\n",
       "\n",
       "[751 rows x 1 columns]"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft['2013-1-15':'2013-1-15 12:30:00']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To select a single row, use .loc:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "A   -3.286898\n",
       "Name: 2013-01-15 12:30:00, dtype: float64"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft.loc['2013-1-15 12:30:00']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Datetime indexing\n",
    "\n",
    "Indexing a DateTimeIndex with a partial string depends on the “accuracy” of the period, in other words how specific the interval is in relation to the frequency of the index. In contrast, indexing with datetime objects is exact, because the objects have exact meaning. These also follow the semantics of including both endpoints.\n",
    "\n",
    "These datetime objects are specific hours, minutes, and seconds even though they were not explicitly specified (they are 0)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:00:00</th>\n",
       "      <td>-0.397880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:01:00</th>\n",
       "      <td>-1.259224</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:02:00</th>\n",
       "      <td>-0.688879</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:03:00</th>\n",
       "      <td>0.802630</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 00:04:00</th>\n",
       "      <td>0.272391</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-27 23:56:00</th>\n",
       "      <td>0.702629</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-27 23:57:00</th>\n",
       "      <td>-1.015303</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-27 23:58:00</th>\n",
       "      <td>-0.433161</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-27 23:59:00</th>\n",
       "      <td>-0.010935</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 00:00:00</th>\n",
       "      <td>0.466138</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>83521 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                            A\n",
       "2013-01-01 00:00:00 -0.397880\n",
       "2013-01-01 00:01:00 -1.259224\n",
       "2013-01-01 00:02:00 -0.688879\n",
       "2013-01-01 00:03:00  0.802630\n",
       "2013-01-01 00:04:00  0.272391\n",
       "...                       ...\n",
       "2013-02-27 23:56:00  0.702629\n",
       "2013-02-27 23:57:00 -1.015303\n",
       "2013-02-27 23:58:00 -0.433161\n",
       "2013-02-27 23:59:00 -0.010935\n",
       "2013-02-28 00:00:00  0.466138\n",
       "\n",
       "[83521 rows x 1 columns]"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft[pd.datetime(2013, 1, 1):pd.datetime(2013, 2, 28)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With no defaults:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:12:00</th>\n",
       "      <td>0.940664</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:13:00</th>\n",
       "      <td>-0.252741</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:14:00</th>\n",
       "      <td>1.206421</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:15:00</th>\n",
       "      <td>-1.173520</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:16:00</th>\n",
       "      <td>-0.909358</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 10:08:00</th>\n",
       "      <td>0.303487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 10:09:00</th>\n",
       "      <td>-0.983036</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 10:10:00</th>\n",
       "      <td>-0.226473</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 10:11:00</th>\n",
       "      <td>0.180549</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-02-28 10:12:00</th>\n",
       "      <td>-0.167137</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>83521 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                            A\n",
       "2013-01-01 10:12:00  0.940664\n",
       "2013-01-01 10:13:00 -0.252741\n",
       "2013-01-01 10:14:00  1.206421\n",
       "2013-01-01 10:15:00 -1.173520\n",
       "2013-01-01 10:16:00 -0.909358\n",
       "...                       ...\n",
       "2013-02-28 10:08:00  0.303487\n",
       "2013-02-28 10:09:00 -0.983036\n",
       "2013-02-28 10:10:00 -0.226473\n",
       "2013-02-28 10:11:00  0.180549\n",
       "2013-02-28 10:12:00 -0.167137\n",
       "\n",
       "[83521 rows x 1 columns]"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dft[pd.datetime(2013, 1, 1, 10, 12, 0):pd.datetime(2013, 2, 28, 10, 12, 0)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Truncating & fancy indexing\n",
    "\n",
    "A truncate convenience function is provided that is equivalent to slicing:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-10-31    0.146560\n",
       "2011-11-30   -0.466351\n",
       "2011-12-30    0.356223\n",
       "Freq: BM, dtype: float64"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.truncate(before='10/31/2011', after='12/31/2011')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Even complicated fancy indexing that breaks the DatetimeIndex’s frequency regularity will result in a DatetimeIndex (but frequency is lost):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-31', '2011-03-31', '2011-07-29'], dtype='datetime64[ns]', freq=None)"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts[[0, 2, 6]].index"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Time/Date Components\n",
    "\n",
    "There are several time/date properties that one can access from Timestamp or a collection of timestamps like a DateTimeIndex.\n",
    "\n",
    "\n",
    "Property | Description\n",
    "---------|------------\n",
    "year | The year of the datetime\n",
    "month | The month of the datetime\n",
    "day | The days of the datetime\n",
    "hour | The hour of the datetime\n",
    "minute | The minutes of the datetime\n",
    "second | The seconds of the datetime\n",
    "microsecond | The microseconds of the datetime\n",
    "nanosecond | The nanoseconds of the datetime\n",
    "date | Returns datetime.date\n",
    "time | Returns datetime.time\n",
    "dayofyear | The ordinal day of year\n",
    "weekofyear | The week ordinal of the year\n",
    "week | The week ordinal of the year\n",
    "dayofweek | The day of the week with Monday=0, Sunday=6\n",
    "weekday | The day of the week with Monday=0, Sunday=6\n",
    "quarter | Quarter of the date: Jan=Mar = 1, Apr-Jun = 2, etc.\n",
    "days_in_month | The number of days in the month of the datetime\n",
    "is_month_start | Logical indicating if first day of month (defined by frequency)\n",
    "is_month_end | Logical indicating if last day of month (defined by frequency)\n",
    "is_quarter_start | Logical indicating if first day of quarter (defined by frequency)\n",
    "is_quarter_end | Logical indicating if last day of quarter (defined by frequency)\n",
    "is_year_start | Logical indicating if first day of year (defined by frequency)\n",
    "is_year_end | Logical indicating if last day of year (defined by frequency)\n",
    "\n",
    "Furthermore, if you have a Series with datetimelike values, then you can access these properties via the .dt accessor, see the docs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01-31   -0.571817\n",
       "2011-02-28   -0.603299\n",
       "2011-03-31   -1.339389\n",
       "2011-04-29   -1.689653\n",
       "2011-05-31   -0.199327\n",
       "                ...   \n",
       "2011-08-31   -1.001002\n",
       "2011-09-30   -2.091691\n",
       "2011-10-31    0.146560\n",
       "2011-11-30   -0.466351\n",
       "2011-12-30    0.356223\n",
       "Freq: BM, Length: 12, dtype: float64"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Int64Index([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], dtype='int64')"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.index.month"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"dateoffset-objects\"></a>\n",
    "\n",
    "## DateOffset objects\n",
    "\n",
    "In the preceding examples, we created DatetimeIndex objects at various frequencies by passing in frequency strings like 'M', 'W', and 'BM' to the freq keyword. Under the hood, these frequency strings are being translated into an instance of pandas DateOffset, which represents a regular frequency increment. Specific offset logic like “month”, “business day”, or “one hour” is represented in its various subclasses.\n",
    "\n",
    "Class name | Description\n",
    "-----------|------------\n",
    "DateOffset | Generic offset class, defaults to 1 calendar day\n",
    "BDay | business day (weekday)\n",
    "CDay | custom business day (experimental)\n",
    "Week | one week, optionally anchored on a day of the week\n",
    "WeekOfMonth | the x-th day of the y-th week of each month\n",
    "LastWeekOfMonth | the x-th day of the last week of each month\n",
    "MonthEnd | calendar month end\n",
    "MonthBegin | calendar month begin\n",
    "BMonthEnd | business month end\n",
    "BMonthBegin | business month begin\n",
    "CBMonthEnd | custom business month end\n",
    "CBMonthBegin | custom business month begin\n",
    "QuarterEnd | calendar quarter end\n",
    "QuarterBegin | calendar quarter begin\n",
    "BQuarterEnd | business quarter end\n",
    "BQuarterBegin | business quarter begin\n",
    "FY5253Quarter | retail (aka 52-53 week) quarter\n",
    "YearEnd | calendar year end\n",
    "YearBegin | calendar year begin\n",
    "BYearEnd | business year end\n",
    "BYearBegin | business year begin\n",
    "FY5253 | retail (aka 52-53 week) year\n",
    "BusinessHour | business hour\n",
    "Hour | one hour\n",
    "Minute | one minute\n",
    "Second | one second\n",
    "Milli | one millisecond\n",
    "Micro | one microsecond\n",
    "Nano | one nanosecond"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Basic function of DateOffset:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = pd.datetime(2018, 2, 27, 9, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "datetime.datetime(2018, 2, 27, 9, 0)"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-02-27 09:00:00')"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-04-28 09:00:00')"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d + pd.tseries.offsets.DateOffset(months=2, days=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The key features of a DateOffset object are:\n",
    "\n",
    "* it can be added / subtracted to/from a datetime object to obtain a shifted date\n",
    "* it can be multiplied by an integer (positive or negative) so that the increment will be applied multiple times\n",
    "* it has rollforward and rollback methods for moving a date forward or backward to the next or previous “offset date”\n",
    "\n",
    "Subclasses of DateOffset define the apply function which dictates custom date increment logic, such as adding business days:\n",
    "\n",
    "    class BDay(DateOffset):\n",
    "        \"\"\"DateOffset increments between business days\"\"\"\n",
    "        def apply(self, other):\n",
    "            ..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-02-20 09:00:00')"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d - 5 * pd.tseries.offsets.BDay()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-02-28 09:00:00')"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d + pd.tseries.offsets.BMonthEnd()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The rollforward and rollback methods do exactly what you would expect:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "datetime.datetime(2018, 2, 27, 9, 0)"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [],
   "source": [
    "offset = pd.tseries.offsets.BMonthEnd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-02-28 09:00:00')"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "offset.rollforward(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-01-31 09:00:00')"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "offset.rollback(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you expect to use these functions, explore the pandas.tseries.offsets module and the various docstrings for the classes.\n",
    "\n",
    "These operations (apply, rollforward and rollback) preserves time (hour, minute, etc) information by default. To reset time, use normalize=True keyword when creating the offset instance. If normalize=True, result is normalized after the function is applied."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [],
   "source": [
    "day = pd.tseries.offsets.Day()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2014-01-02 09:00:00')"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "day.apply(pd.Timestamp('2014-01-01 09:00'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [],
   "source": [
    "day = pd.tseries.offsets.Day(normalize=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2014-01-02 00:00:00')"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "day.apply(pd.Timestamp('2014-01-01 09:00'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [],
   "source": [
    "hour = pd.tseries.offsets.Hour()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2014-01-01 23:00:00')"
      ]
     },
     "execution_count": 113,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hour.apply(pd.Timestamp('2014-01-01 22:00'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2014-01-01 23:00:00')"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('2014-01-01 23:00:00')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "hour = pd.tseries.offsets.Hour(normalize=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2014-01-01 00:00:00')"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hour.apply(pd.Timestamp('2014-01-01 22:00'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2014-01-02 00:00:00')"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hour.apply(pd.Timestamp('2014-01-01 23:00'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parametric offsets\n",
    "\n",
    "Some of the offsets can be “parameterized” when created to result in different behaviors. For example, the Week offset for generating weekly data accepts a weekday parameter which results in the generated dates always lying on a particular day of the week:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "datetime.datetime(2018, 2, 27, 9, 0)"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-03-06 09:00:00')"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d + pd.tseries.offsets.Week()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-03-02 09:00:00')"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d + pd.tseries.offsets.Week(weekday=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(d + pd.tseries.offsets.Week(weekday=4)).weekday()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-02-20 09:00:00')"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d - pd.tseries.offsets.Week()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "normalize option will be effective for addition and subtraction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-03-06 00:00:00')"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d + pd.tseries.offsets.Week(normalize=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-02-20 00:00:00')"
      ]
     },
     "execution_count": 124,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d - pd.tseries.offsets.Week(normalize=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another example is parameterizing YearEnd with the specific ending month:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-12-31 09:00:00')"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d + pd.tseries.offsets.YearEnd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-06-30 09:00:00')"
      ]
     },
     "execution_count": 126,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d + pd.tseries.offsets.YearEnd(month=6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using offsets with Series / DatetimeIndex\n",
    "\n",
    "Offsets can be used with either a Series or DatetimeIndex to apply the offset to each element."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng = pd.date_range('2012-01-01', '2012-01-03')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = pd.Series(rng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-01-01', '2012-01-02', '2012-01-03'], dtype='datetime64[ns]', freq='D')"
      ]
     },
     "execution_count": 129,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-03-01', '2012-03-02', '2012-03-03'], dtype='datetime64[ns]', freq='D')"
      ]
     },
     "execution_count": 130,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng + pd.tseries.offsets.DateOffset(months=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2012-03-01\n",
       "1   2012-03-02\n",
       "2   2012-03-03\n",
       "dtype: datetime64[ns]"
      ]
     },
     "execution_count": 131,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s + pd.tseries.offsets.DateOffset(months=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2011-11-01\n",
       "1   2011-11-02\n",
       "2   2011-11-03\n",
       "dtype: datetime64[ns]"
      ]
     },
     "execution_count": 132,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s - pd.tseries.offsets.DateOffset(months=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If the offset class maps directly to a Timedelta (Day, Hour, Minute, Second, Micro, Milli, Nano) it can be used exactly like a Timedelta - see the Timedelta section for more examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2011-12-30\n",
       "1   2011-12-31\n",
       "2   2012-01-01\n",
       "dtype: datetime64[ns]"
      ]
     },
     "execution_count": 133,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s - pd.tseries.offsets.Day(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {},
   "outputs": [],
   "source": [
    "td = s - pd.Series(pd.date_range('2011-12-29', '2011-12-31'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   3 days\n",
       "1   3 days\n",
       "2   3 days\n",
       "dtype: timedelta64[ns]"
      ]
     },
     "execution_count": 135,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "td"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   3 days 00:15:00\n",
       "1   3 days 00:15:00\n",
       "2   3 days 00:15:00\n",
       "dtype: timedelta64[ns]"
      ]
     },
     "execution_count": 136,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "td + pd.tseries.offsets.Minute(15)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that some offsets (such as BQuarterEnd) do not have a vectorized implementation. They can still be used but may calculate signficantly slower and will raise a PerformanceWarning."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-03-30', '2012-03-30', '2012-03-30'], dtype='datetime64[ns]', freq='D')"
      ]
     },
     "execution_count": 137,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng + pd.tseries.offsets.BQuarterEnd()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Offset Aliases\n",
    "\n",
    "A number of string aliases are given to useful common time series frequencies. We will refer to these aliases as offset aliases (referred to as time rules prior to v0.8.0).\n",
    "\n",
    "Alias | Description\n",
    "------|------------\n",
    "B | business day frequency\n",
    "C | custom business day frequency (experimental)\n",
    "D | calendar day frequency\n",
    "W | weekly frequency\n",
    "M | month end frequency\n",
    "BM | business month end frequency\n",
    "CBM | custom business month end frequency\n",
    "MS | month start frequency\n",
    "BMS | business month start frequency\n",
    "CBMS | custom business month start frequency\n",
    "Q | quarter end frequency\n",
    "BQ | business quarter endfrequency\n",
    "QS | quarter start frequency\n",
    "BQS | business quarter start frequency\n",
    "A | year end frequency\n",
    "BA | business year end frequency\n",
    "AS | year start frequency\n",
    "BAS | business year start frequency\n",
    "BH | business hour frequency\n",
    "H | hourly frequency\n",
    "T, min | minutely frequency\n",
    "S | secondly frequency\n",
    "L, ms | milliseonds\n",
    "U, us | microseconds\n",
    "N | nanoseconds"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Combining Aliases\n",
    "\n",
    "As we have seen previously, the alias and the offset instance are fungible in most functions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-03', '2011-01-04', '2011-01-05', '2011-01-06',\n",
       "               '2011-01-07'],\n",
       "              dtype='datetime64[ns]', freq='B')"
      ]
     },
     "execution_count": 138,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start, periods=5, freq='B')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-03', '2011-01-04', '2011-01-05', '2011-01-06',\n",
       "               '2011-01-07'],\n",
       "              dtype='datetime64[ns]', freq='B')"
      ]
     },
     "execution_count": 139,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start, periods=5, freq=pd.tseries.offsets.BDay())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can combine together day and intraday offsets:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2011-01-01 00:00:00', '2011-01-01 02:20:00',\n",
       "               '2011-01-01 04:40:00', '2011-01-01 07:00:00',\n",
       "               '2011-01-01 09:20:00', '2011-01-01 11:40:00',\n",
       "               '2011-01-01 14:00:00', '2011-01-01 16:20:00',\n",
       "               '2011-01-01 18:40:00', '2011-01-01 21:00:00'],\n",
       "              dtype='datetime64[ns]', freq='140T')"
      ]
     },
     "execution_count": 140,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start, periods=10, freq='2h20min')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex([       '2011-01-01 00:00:00', '2011-01-02 00:00:00.000010',\n",
       "               '2011-01-03 00:00:00.000020', '2011-01-04 00:00:00.000030',\n",
       "               '2011-01-05 00:00:00.000040', '2011-01-06 00:00:00.000050',\n",
       "               '2011-01-07 00:00:00.000060', '2011-01-08 00:00:00.000070',\n",
       "               '2011-01-09 00:00:00.000080', '2011-01-10 00:00:00.000090'],\n",
       "              dtype='datetime64[ns]', freq='86400000010U')"
      ]
     },
     "execution_count": 141,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.date_range(start, periods=10, freq='1D10U')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"instance-methods\"></a>\n",
    "\n",
    "## Time series-related instance methods\n",
    "\n",
    "### Shifting / lagging\n",
    "\n",
    "One may want to shift or lag the values in a time series back and forward in time. The method for this is shift, which is available on all of the pandas objects."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = pd.Series(['a', 'b', 'c', 'd', 'e'], index=pd.date_range(start='3/1/18', periods=5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2018-03-01    a\n",
       "2018-03-02    b\n",
       "2018-03-03    c\n",
       "2018-03-04    d\n",
       "2018-03-05    e\n",
       "Freq: D, dtype: object"
      ]
     },
     "execution_count": 143,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2018-03-01    NaN\n",
       "2018-03-02    NaN\n",
       "2018-03-03    NaN\n",
       "2018-03-04      a\n",
       "2018-03-05      b\n",
       "Freq: D, dtype: object"
      ]
     },
     "execution_count": 144,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.shift(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notes: If freq is specified then the index values are shifted but the data\n",
    "is not realigned. That is, use freq if you would like to extend the\n",
    "index when shifting and preserve the original data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2018-03-04    a\n",
       "2018-03-05    b\n",
       "2018-03-06    c\n",
       "2018-03-07    d\n",
       "2018-03-08    e\n",
       "Freq: D, dtype: object"
      ]
     },
     "execution_count": 145,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.shift(3, freq='D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2018-05-31    a\n",
       "2018-05-31    b\n",
       "2018-05-31    c\n",
       "2018-05-31    d\n",
       "2018-05-31    e\n",
       "Freq: D, dtype: object"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.shift(3, freq='M')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The same thing can be accomplisehd with the tshift convenience method that changes all the dates in the index by a specified number of offsets, rather than changing the alignment of the data and the index:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2018-03-04    a\n",
       "2018-03-05    b\n",
       "2018-03-06    c\n",
       "2018-03-07    d\n",
       "2018-03-08    e\n",
       "Freq: D, dtype: object"
      ]
     },
     "execution_count": 147,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.tshift(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that with tshift (and with shift+freq), the leading entry is no longer NaN because the data is not being realigned."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Frequency conversion\n",
    "\n",
    "The primary function for changing frequencies is the asfreq function. For a DatetimeIndex, this is a convenient wrapper around reindex which generates a date_range and calls reindex."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {},
   "outputs": [],
   "source": [
    "dr = pd.date_range('1/1/2010', periods=3, freq='3B')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = pd.Series(np.random.randn(3), index=dr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2010-01-01   -0.879905\n",
       "2010-01-06   -1.414049\n",
       "2010-01-11    0.758031\n",
       "Freq: 3B, dtype: float64"
      ]
     },
     "execution_count": 150,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2010-01-01   -0.879905\n",
       "2010-01-04         NaN\n",
       "2010-01-05         NaN\n",
       "2010-01-06   -1.414049\n",
       "2010-01-07         NaN\n",
       "2010-01-08         NaN\n",
       "2010-01-11    0.758031\n",
       "Freq: B, dtype: float64"
      ]
     },
     "execution_count": 151,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.asfreq('B')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "asfreq provides a further convenience so you can specify an interpolation method (e.g. 'pad', i.e. forward fill) for any gaps that may appear after the frequency conversion."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2010-01-01   -0.879905\n",
       "2010-01-04   -0.879905\n",
       "2010-01-05   -0.879905\n",
       "2010-01-06   -1.414049\n",
       "2010-01-07   -1.414049\n",
       "2010-01-08   -1.414049\n",
       "2010-01-11    0.758031\n",
       "Freq: B, dtype: float64"
      ]
     },
     "execution_count": 152,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.asfreq(pd.tseries.offsets.BDay(), method='pad')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Filling forward / backward\n",
    "\n",
    "Related to asfreq and reindex is the fillna function, which can be used with any Pandas object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2010-01-01   -0.879905\n",
       "2010-01-04    0.000000\n",
       "2010-01-05    0.000000\n",
       "2010-01-06   -1.414049\n",
       "2010-01-07    0.000000\n",
       "2010-01-08    0.000000\n",
       "2010-01-11    0.758031\n",
       "Freq: B, dtype: float64"
      ]
     },
     "execution_count": 153,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.asfreq('B').fillna(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"time-spans\"></a>\n",
    "\n",
    "## Time span representation\n",
    "\n",
    "Regular intervals of time are represented by Period objects in pandas while sequences of Period objects are collected in a PeriodIndex, which can be created with the convenience function period_range.\n",
    "\n",
    "### Period\n",
    "\n",
    "A Period represents a span of time (e.g., a day, a month, a quarter, etc). You can specify the span via freq keyword using a frequency alias like below. Because freq represents a span of Period, it cannot be negative like \"-3D\". ('A-DEC' is annual frequency, anchored end of December; same as 'A'.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2012', 'A-DEC')"
      ]
     },
     "execution_count": 154,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period('2012', freq='A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2012-01-01', 'D')"
      ]
     },
     "execution_count": 155,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period('2012-1-1', freq='D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2012-01-01 19:00', 'H')"
      ]
     },
     "execution_count": 156,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period('2012-1-1 19:00', freq='H')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2012-01-01 19:00', '5H')"
      ]
     },
     "execution_count": 157,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period('2012-1-1 19:00', freq='5H')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Adding and subtracting integers from periods shifts the period by its own frequency. Arithmetic is not allowed between Period with different freq (span)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = pd.Period('2012', freq='A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2013', 'A-DEC')"
      ]
     },
     "execution_count": 159,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2009', 'A-DEC')"
      ]
     },
     "execution_count": 160,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p - 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = pd.Period('2012-01', freq='2M')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2012-05', '2M')"
      ]
     },
     "execution_count": 162,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p + 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2011-11', '2M')"
      ]
     },
     "execution_count": 163,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p - 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If Period freq is daily or higher (D, H, T, S, L, U, N), offsets and timedelta-like can be added if the result can have the same freq."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = pd.Period('2014-07-01 09:00', freq='H')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2014-07-01 11:00', 'H')"
      ]
     },
     "execution_count": 165,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p + pd.tseries.offsets.Hour(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2014-07-01 11:00', 'H')"
      ]
     },
     "execution_count": 166,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p + pd.tseries.offsets.timedelta(minutes=120)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 167,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2014-07-01 11:00', 'H')"
      ]
     },
     "execution_count": 167,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p + np.timedelta64(7200, 's')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If Period has other freqs, only the same offsets can be added."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 168,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = pd.Period('2014-07', freq='M')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 169,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2014-10', 'M')"
      ]
     },
     "execution_count": 169,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p + pd.tseries.offsets.MonthEnd(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 170,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 170,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period('2012', freq='A') - pd.Period('2002', freq='A')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Periods vs. Timestamps\n",
    "\n",
    "Notice the difference between Timestamps and Periods in determining differences in times."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 171,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timedelta('17854 days 13:25:57.847288')"
      ]
     },
     "execution_count": 171,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.datetime.today() - pd.Timestamp('1/1/1970')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "17854"
      ]
     },
     "execution_count": 172,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period(pd.datetime.today(), 'D') - pd.Period('1/1/1970', 'D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "48"
      ]
     },
     "execution_count": 173,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Period(pd.datetime.today(), 'A') - pd.Period('1/1/1970', 'A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 174,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timedelta('17854 days 13:25:57.875449')"
      ]
     },
     "execution_count": 174,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t = pd.datetime.today() - pd.Timestamp('1/1/1970')\n",
    "t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 175,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "17854"
      ]
     },
     "execution_count": 175,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t.days"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PeriodIndex and period_range\n",
    "\n",
    "Regular sequences of Period objects can be collected in a PeriodIndex, which can be constructed using the period_range convenience function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 176,
   "metadata": {},
   "outputs": [],
   "source": [
    "prng = pd.period_range('1/1/2011', '1/1/2012', freq='M')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04', '2011-05', '2011-06',\n",
       "             '2011-07', '2011-08', '2011-09', '2011-10', '2011-11', '2011-12',\n",
       "             '2012-01'],\n",
       "            dtype='period[M]', freq='M')"
      ]
     },
     "execution_count": 177,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prng"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The PeriodIndex constructor can also be used directly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2011-01', '2011-02', '2011-03'], dtype='period[M]', freq='M')"
      ]
     },
     "execution_count": 178,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.PeriodIndex(['2011-1', '2011-2', '2011-3'], freq='M')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Passing multiplied frequency outputs a sequence of Period which has multiplied span."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2014-01', '2014-04', '2014-07', '2014-10'], dtype='period[3M]', freq='3M')"
      ]
     },
     "execution_count": 179,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.PeriodIndex(start='2014-01', freq='3M', periods=4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Just like DatetimeIndex, a PeriodIndex can also be used to index pandas objects:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "metadata": {},
   "outputs": [],
   "source": [
    "ps = pd.Series(np.random.randn(len(prng)), prng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 181,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01    0.610397\n",
       "2011-02    2.718729\n",
       "2011-03    0.123990\n",
       "2011-04    0.061996\n",
       "2011-05   -1.098168\n",
       "             ...   \n",
       "2011-09   -0.121368\n",
       "2011-10   -0.684034\n",
       "2011-11   -0.936657\n",
       "2011-12   -0.925786\n",
       "2012-01   -0.039955\n",
       "Freq: M, Length: 13, dtype: float64"
      ]
     },
     "execution_count": 181,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "PeriodIndex supports addition and subtraction with the same rule as Period."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 182,
   "metadata": {},
   "outputs": [],
   "source": [
    "idx = pd.period_range('2014-07-01 09:00', periods=5, freq='H')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2014-07-01 09:00', '2014-07-01 10:00', '2014-07-01 11:00',\n",
       "             '2014-07-01 12:00', '2014-07-01 13:00'],\n",
       "            dtype='period[H]', freq='H')"
      ]
     },
     "execution_count": 183,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "idx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00',\n",
       "             '2014-07-01 14:00', '2014-07-01 15:00'],\n",
       "            dtype='period[H]', freq='H')"
      ]
     },
     "execution_count": 184,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "idx + pd.tseries.offsets.Hour(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {},
   "outputs": [],
   "source": [
    "idx = pd.period_range('2014-07', periods=5, freq='M')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2014-07', '2014-08', '2014-09', '2014-10', '2014-11'], dtype='period[M]', freq='M')"
      ]
     },
     "execution_count": 186,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "idx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 187,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2014-10', '2014-11', '2014-12', '2015-01', '2015-02'], dtype='period[M]', freq='M')"
      ]
     },
     "execution_count": 187,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "idx + pd.tseries.offsets.MonthEnd(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PeriodIndex partial string indexing\n",
    "\n",
    "You can pass in dates and strings to Series and DataFrame with PeriodIndex, in the same manner as DatetimeIndex. For details, refer to DatetimeIndex Partial String Indexing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 188,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01    0.610397\n",
       "2011-02    2.718729\n",
       "2011-03    0.123990\n",
       "2011-04    0.061996\n",
       "2011-05   -1.098168\n",
       "             ...   \n",
       "2011-09   -0.121368\n",
       "2011-10   -0.684034\n",
       "2011-11   -0.936657\n",
       "2011-12   -0.925786\n",
       "2012-01   -0.039955\n",
       "Freq: M, Length: 13, dtype: float64"
      ]
     },
     "execution_count": 188,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 189,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6103969193827244"
      ]
     },
     "execution_count": 189,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps['2011-01']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 190,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-12   -0.925786\n",
       "2012-01   -0.039955\n",
       "Freq: M, dtype: float64"
      ]
     },
     "execution_count": 190,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps[pd.datetime(2011, 12, 25):]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 191,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-10   -0.684034\n",
       "2011-11   -0.936657\n",
       "2011-12   -0.925786\n",
       "Freq: M, dtype: float64"
      ]
     },
     "execution_count": 191,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps['10/31/2011':'12/31/2011']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Passing a string representing a lower frequency than PeriodIndex returns partial sliced data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 192,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2011-01    0.610397\n",
       "2011-02    2.718729\n",
       "2011-03    0.123990\n",
       "2011-04    0.061996\n",
       "2011-05   -1.098168\n",
       "             ...   \n",
       "2011-08   -0.055498\n",
       "2011-09   -0.121368\n",
       "2011-10   -0.684034\n",
       "2011-11   -0.936657\n",
       "2011-12   -0.925786\n",
       "Freq: M, Length: 12, dtype: float64"
      ]
     },
     "execution_count": 192,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps['2011']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 193,
   "metadata": {},
   "outputs": [],
   "source": [
    "dfp = pd.DataFrame(np.random.randn(600,1), columns=['A'], index=pd.period_range('2013-01-01 9:00', \n",
    "                                                                                periods=600, freq='T'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 09:00</th>\n",
       "      <td>-0.202472</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 09:01</th>\n",
       "      <td>0.471613</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 09:02</th>\n",
       "      <td>0.412381</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 09:03</th>\n",
       "      <td>1.468281</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 09:04</th>\n",
       "      <td>-0.029521</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 18:55</th>\n",
       "      <td>-3.541275</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 18:56</th>\n",
       "      <td>0.647991</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 18:57</th>\n",
       "      <td>-0.192105</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 18:58</th>\n",
       "      <td>1.653897</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 18:59</th>\n",
       "      <td>-0.476042</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>600 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                         A\n",
       "2013-01-01 09:00 -0.202472\n",
       "2013-01-01 09:01  0.471613\n",
       "2013-01-01 09:02  0.412381\n",
       "2013-01-01 09:03  1.468281\n",
       "2013-01-01 09:04 -0.029521\n",
       "...                    ...\n",
       "2013-01-01 18:55 -3.541275\n",
       "2013-01-01 18:56  0.647991\n",
       "2013-01-01 18:57 -0.192105\n",
       "2013-01-01 18:58  1.653897\n",
       "2013-01-01 18:59 -0.476042\n",
       "\n",
       "[600 rows x 1 columns]"
      ]
     },
     "execution_count": 194,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dfp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:00</th>\n",
       "      <td>-0.214422</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:01</th>\n",
       "      <td>0.914302</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:02</th>\n",
       "      <td>1.256289</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:03</th>\n",
       "      <td>-0.670824</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:04</th>\n",
       "      <td>0.425011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:55</th>\n",
       "      <td>-0.496025</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:56</th>\n",
       "      <td>0.406034</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:57</th>\n",
       "      <td>0.639487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:58</th>\n",
       "      <td>0.585937</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:59</th>\n",
       "      <td>0.364989</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>60 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                         A\n",
       "2013-01-01 10:00 -0.214422\n",
       "2013-01-01 10:01  0.914302\n",
       "2013-01-01 10:02  1.256289\n",
       "2013-01-01 10:03 -0.670824\n",
       "2013-01-01 10:04  0.425011\n",
       "...                    ...\n",
       "2013-01-01 10:55 -0.496025\n",
       "2013-01-01 10:56  0.406034\n",
       "2013-01-01 10:57  0.639487\n",
       "2013-01-01 10:58  0.585937\n",
       "2013-01-01 10:59  0.364989\n",
       "\n",
       "[60 rows x 1 columns]"
      ]
     },
     "execution_count": 195,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dfp['2013-01-01 10H']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As with DatetimeIndex, the endpoints will be included in the result. The example below slices data starting from 10:00 to 11:59."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 196,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:00</th>\n",
       "      <td>-0.214422</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:01</th>\n",
       "      <td>0.914302</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:02</th>\n",
       "      <td>1.256289</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:03</th>\n",
       "      <td>-0.670824</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 10:04</th>\n",
       "      <td>0.425011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 11:55</th>\n",
       "      <td>-0.487586</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 11:56</th>\n",
       "      <td>-0.511452</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 11:57</th>\n",
       "      <td>-0.223774</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 11:58</th>\n",
       "      <td>-0.019521</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-01-01 11:59</th>\n",
       "      <td>-1.142647</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>120 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                         A\n",
       "2013-01-01 10:00 -0.214422\n",
       "2013-01-01 10:01  0.914302\n",
       "2013-01-01 10:02  1.256289\n",
       "2013-01-01 10:03 -0.670824\n",
       "2013-01-01 10:04  0.425011\n",
       "...                    ...\n",
       "2013-01-01 11:55 -0.487586\n",
       "2013-01-01 11:56 -0.511452\n",
       "2013-01-01 11:57 -0.223774\n",
       "2013-01-01 11:58 -0.019521\n",
       "2013-01-01 11:59 -1.142647\n",
       "\n",
       "[120 rows x 1 columns]"
      ]
     },
     "execution_count": 196,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dfp['2013-01-01 10H':'2013-01-01 11H']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Frequency conversion and resampling with PeriodIndex\n",
    "\n",
    "The frequency of Period and PeriodIndex can be converted via the asfreq method. Let’s start with the fiscal year 2011, ending in December:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 197,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = pd.Period('2011', freq='A-DEC')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 198,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2011', 'A-DEC')"
      ]
     },
     "execution_count": 198,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can convert it to a monthly frequency. Using the how parameter, we can specify whether to return the starting or ending month:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 199,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2011-01', 'M')"
      ]
     },
     "execution_count": 199,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p.asfreq('M', how='start')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 200,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Period('2011-12', 'M')"
      ]
     },
     "execution_count": 200,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p.asfreq('M', how='end')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Converting between representations\n",
    "\n",
    "Timestamped data can be converted to PeriodIndex-ed data using to_period and vice-versa using to_timestamp:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 201,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng = pd.date_range('1/1/2012', periods=5, freq='M')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 202,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = pd.Series(np.random.randn(len(rng)), index=rng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 203,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-01-31   -0.355537\n",
       "2012-02-29   -0.696925\n",
       "2012-03-31   -0.613224\n",
       "2012-04-30    1.052651\n",
       "2012-05-31   -1.458326\n",
       "Freq: M, dtype: float64"
      ]
     },
     "execution_count": 203,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 204,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-01-31', '2012-02-29', '2012-03-31', '2012-04-30',\n",
       "               '2012-05-31'],\n",
       "              dtype='datetime64[ns]', freq='M')"
      ]
     },
     "execution_count": 204,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 205,
   "metadata": {},
   "outputs": [],
   "source": [
    "ps = ts.to_period()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 206,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-01   -0.355537\n",
       "2012-02   -0.696925\n",
       "2012-03   -0.613224\n",
       "2012-04    1.052651\n",
       "2012-05   -1.458326\n",
       "Freq: M, dtype: float64"
      ]
     },
     "execution_count": 206,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 207,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PeriodIndex(['2012-01', '2012-02', '2012-03', '2012-04', '2012-05'], dtype='period[M]', freq='M')"
      ]
     },
     "execution_count": 207,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 208,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-01-01   -0.355537\n",
       "2012-02-01   -0.696925\n",
       "2012-03-01   -0.613224\n",
       "2012-04-01    1.052651\n",
       "2012-05-01   -1.458326\n",
       "Freq: MS, dtype: float64"
      ]
     },
     "execution_count": 208,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps.to_timestamp()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 209,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-01-01   -0.355537\n",
       "2012-02-01   -0.696925\n",
       "2012-03-01   -0.613224\n",
       "2012-04-01    1.052651\n",
       "2012-05-01   -1.458326\n",
       "Freq: MS, dtype: float64"
      ]
     },
     "execution_count": 209,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps.to_timestamp('D', how='start')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 210,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-01-31   -0.355537\n",
       "2012-02-29   -0.696925\n",
       "2012-03-31   -0.613224\n",
       "2012-04-30    1.052651\n",
       "2012-05-31   -1.458326\n",
       "Freq: M, dtype: float64"
      ]
     },
     "execution_count": 210,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps.to_timestamp('D', how='end')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id=\"time-zones\"></a>\n",
    "\n",
    "## Time zone handling\n",
    "\n",
    "Pandas provides rich support for working with timestamps in different time zones using pytz and dateutil libraries. dateutil support is new in 0.14.1 and currently only supported for fixed offset and tzfile zones. The default library is pytz. Support for dateutil is provided for compatibility with other applications e.g. if you use dateutil in other python packages.\n",
    "\n",
    "### Working with time zones\n",
    "\n",
    "By default, pandas objects are time zone unaware:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 211,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng = pd.date_range('3/6/2012 00:00', periods=15, freq='D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 212,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 212,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng.tz is None"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To supply the time zone, you can use the tz keyword to date_range and other functions. There are two options for time zone formats:\n",
    "\n",
    "* pytz - pytz brings the Olson tz database into Python. This library allows accurate and cross platform timezone calculations using Python 2.4 or higher. You can find a list of common (and less common) time zones using from pytz import common_timezones, all_timezones. For UTC, there is a special case tzutc.\n",
    "* dateutil - The dateutil module provides powerful extensions to the datetime module available in the Python standard library. It uses the OS timezones so there isn’t a fixed list available. For common zones, the names are the same as pytz. Dateutil time zone strings are distinguished from pytz time zones by starting with \"dateutil/\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 213,
   "metadata": {},
   "outputs": [],
   "source": [
    "# pytz\n",
    "rng_pytz = pd.date_range('3/6/2012 00:00', periods=10, freq='D', tz='Europe/London')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 214,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>"
      ]
     },
     "execution_count": 214,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_pytz.tz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 215,
   "metadata": {},
   "outputs": [],
   "source": [
    "# dateutil\n",
    "rng_dateutil = pd.date_range('3/6/2012 00:00', periods=10, freq='D', tz='dateutil/Europe/London')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 216,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tzfile('/usr/share/zoneinfo/Europe/London')"
      ]
     },
     "execution_count": 216,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_dateutil.tz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 217,
   "metadata": {},
   "outputs": [],
   "source": [
    "# dateutil - utc special case\n",
    "rng_utc = pd.date_range('3/6/2012 00:00', periods=10, freq='D', tz=dateutil.tz.tzutc())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 218,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tzutc()"
      ]
     },
     "execution_count": 218,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_utc.tz"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that the UTC timezone is a special case in dateutil and should be constructed explicitly as an instance of dateutil.tz.tzutc. You can also construct other timezones explicitly first, which gives you more control over which time zone is used:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 219,
   "metadata": {},
   "outputs": [],
   "source": [
    "# pytz\n",
    "tz_pytz = pytz.timezone('Europe/London')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 220,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng_pytz = pd.date_range('3/6/2012 00:00', periods=10, freq='D', tz=tz_pytz)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 221,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 221,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_pytz.tz == tz_pytz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 222,
   "metadata": {},
   "outputs": [],
   "source": [
    "# dateutil\n",
    "tz_dateutil = dateutil.tz.gettz('Europe/London')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 223,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng_dateutil = pd.date_range('3/6/2012 00:00', periods=10, freq='D', tz=tz_dateutil)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 224,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 224,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_dateutil.tz == tz_dateutil"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Timestamps, like Python’s datetime.datetime object can be either time zone naive or time zone aware. Naive time series and DatetimeIndex objects can be localized using tz_localize:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 225,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = pd.Series(np.random.randn(len(rng)), rng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 226,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-03-06    1.391462\n",
       "2012-03-07   -0.326334\n",
       "2012-03-08   -0.101728\n",
       "2012-03-09    0.443825\n",
       "2012-03-10   -1.816127\n",
       "                ...   \n",
       "2012-03-16    0.187639\n",
       "2012-03-17   -0.737377\n",
       "2012-03-18   -2.282972\n",
       "2012-03-19   -0.619518\n",
       "2012-03-20    1.777953\n",
       "Freq: D, Length: 15, dtype: float64"
      ]
     },
     "execution_count": 226,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 227,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts_utc = ts.tz_localize('UTC')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 228,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-03-06 00:00:00+00:00    1.391462\n",
       "2012-03-07 00:00:00+00:00   -0.326334\n",
       "2012-03-08 00:00:00+00:00   -0.101728\n",
       "2012-03-09 00:00:00+00:00    0.443825\n",
       "2012-03-10 00:00:00+00:00   -1.816127\n",
       "                               ...   \n",
       "2012-03-16 00:00:00+00:00    0.187639\n",
       "2012-03-17 00:00:00+00:00   -0.737377\n",
       "2012-03-18 00:00:00+00:00   -2.282972\n",
       "2012-03-19 00:00:00+00:00   -0.619518\n",
       "2012-03-20 00:00:00+00:00    1.777953\n",
       "Freq: D, Length: 15, dtype: float64"
      ]
     },
     "execution_count": 228,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts_utc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Again, you can explicitly construct the timezone object first. You can use the tz_convert method to convert pandas objects to convert tz-aware data to another time zone:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 229,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-03-05 19:00:00-05:00    1.391462\n",
       "2012-03-06 19:00:00-05:00   -0.326334\n",
       "2012-03-07 19:00:00-05:00   -0.101728\n",
       "2012-03-08 19:00:00-05:00    0.443825\n",
       "2012-03-09 19:00:00-05:00   -1.816127\n",
       "                               ...   \n",
       "2012-03-15 20:00:00-04:00    0.187639\n",
       "2012-03-16 20:00:00-04:00   -0.737377\n",
       "2012-03-17 20:00:00-04:00   -2.282972\n",
       "2012-03-18 20:00:00-04:00   -0.619518\n",
       "2012-03-19 20:00:00-04:00    1.777953\n",
       "Freq: D, Length: 15, dtype: float64"
      ]
     },
     "execution_count": 229,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts_utc.tz_convert('US/Eastern')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Warnings:\n",
    "\n",
    "* Be wary of conversions between libraries. For some zones pytz and dateutil have different definitions of the zone. This is more of a problem for unusual timezones than for ‘standard’ zones like US/Eastern.\n",
    "* Be aware that a timezone definition across versions of timezone libraries may not be considered equal. This may cause problems when working with stored data that is localized using one version and operated on with a different version. See here for how to handle such a situation.\n",
    "* It is incorrect to pass a timezone directly into the datetime.datetime constructor (e.g., datetime.datetime(2011, 1, 1, tz=timezone('US/Eastern')). Instead, the datetime needs to be localized using the the localize method on the timezone."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Under the hood, all timestamps are stored in UTC. Scalar values from a DatetimeIndex with a time zone will have their fields (day, hour, minute) localized to the time zone. However, timestamps with the same UTC value are still considered to be equal even if they are in different time zones:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 230,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng_eastern = rng_utc.tz_convert('US/Eastern')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 231,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng_berlin = rng_utc.tz_convert('Europe/Berlin')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 232,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-03-10 19:00:00-0500', tz='US/Eastern', freq='D')"
      ]
     },
     "execution_count": 232,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_eastern[5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 233,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-03-11 01:00:00+0100', tz='Europe/Berlin', freq='D')"
      ]
     },
     "execution_count": 233,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_berlin[5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 234,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 234,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_eastern[5] == rng_berlin[5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Like Series, DataFrame, and DatetimeIndex, Timestamps can be converted to other time zones using tz_convert:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 235,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-03-10 19:00:00-0500', tz='US/Eastern', freq='D')"
      ]
     },
     "execution_count": 235,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_eastern[5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 236,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-03-11 01:00:00+0100', tz='Europe/Berlin', freq='D')"
      ]
     },
     "execution_count": 236,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_berlin[5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 237,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-03-11 01:00:00+0100', tz='Europe/Berlin')"
      ]
     },
     "execution_count": 237,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng_eastern[5].tz_convert('Europe/Berlin')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Localization of Timestamps functions just like DatetimeIndex and Series:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 238,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-03-11 00:00:00', freq='D')"
      ]
     },
     "execution_count": 238,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng[5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 239,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2012-03-11 00:00:00+0800', tz='Asia/Shanghai')"
      ]
     },
     "execution_count": 239,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng[5].tz_localize('Asia/Shanghai')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Operations between Series in different time zones will yield UTC Series, aligning the data on the UTC timestamps:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 240,
   "metadata": {},
   "outputs": [],
   "source": [
    "eastern = ts_utc.tz_convert('US/Eastern')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 241,
   "metadata": {},
   "outputs": [],
   "source": [
    "berlin = ts_utc.tz_convert('Europe/Berlin')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 242,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = eastern + berlin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 243,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2012-03-06 00:00:00+00:00    2.782924\n",
       "2012-03-07 00:00:00+00:00   -0.652667\n",
       "2012-03-08 00:00:00+00:00   -0.203455\n",
       "2012-03-09 00:00:00+00:00    0.887650\n",
       "2012-03-10 00:00:00+00:00   -3.632254\n",
       "                               ...   \n",
       "2012-03-16 00:00:00+00:00    0.375278\n",
       "2012-03-17 00:00:00+00:00   -1.474753\n",
       "2012-03-18 00:00:00+00:00   -4.565945\n",
       "2012-03-19 00:00:00+00:00   -1.239035\n",
       "2012-03-20 00:00:00+00:00    3.555907\n",
       "Freq: D, Length: 15, dtype: float64"
      ]
     },
     "execution_count": 243,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 244,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-03-06', '2012-03-07', '2012-03-08', '2012-03-09',\n",
       "               '2012-03-10', '2012-03-11', '2012-03-12', '2012-03-13',\n",
       "               '2012-03-14', '2012-03-15', '2012-03-16', '2012-03-17',\n",
       "               '2012-03-18', '2012-03-19', '2012-03-20'],\n",
       "              dtype='datetime64[ns, UTC]', freq='D')"
      ]
     },
     "execution_count": 244,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result.index"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Other time zones"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "List all the time zones available from pytz:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 245,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Africa/Abidjan\n",
      "Africa/Accra\n",
      "Africa/Addis_Ababa\n",
      "Africa/Algiers\n",
      "Africa/Asmara\n",
      "Africa/Asmera\n",
      "Africa/Bamako\n",
      "Africa/Bangui\n",
      "Africa/Banjul\n",
      "Africa/Bissau\n",
      "Africa/Blantyre\n",
      "Africa/Brazzaville\n",
      "Africa/Bujumbura\n",
      "Africa/Cairo\n",
      "Africa/Casablanca\n",
      "Africa/Ceuta\n",
      "Africa/Conakry\n",
      "Africa/Dakar\n",
      "Africa/Dar_es_Salaam\n",
      "Africa/Djibouti\n",
      "Africa/Douala\n",
      "Africa/El_Aaiun\n",
      "Africa/Freetown\n",
      "Africa/Gaborone\n",
      "Africa/Harare\n",
      "Africa/Johannesburg\n",
      "Africa/Juba\n",
      "Africa/Kampala\n",
      "Africa/Khartoum\n",
      "Africa/Kigali\n",
      "Africa/Kinshasa\n",
      "Africa/Lagos\n",
      "Africa/Libreville\n",
      "Africa/Lome\n",
      "Africa/Luanda\n",
      "Africa/Lubumbashi\n",
      "Africa/Lusaka\n",
      "Africa/Malabo\n",
      "Africa/Maputo\n",
      "Africa/Maseru\n",
      "Africa/Mbabane\n",
      "Africa/Mogadishu\n",
      "Africa/Monrovia\n",
      "Africa/Nairobi\n",
      "Africa/Ndjamena\n",
      "Africa/Niamey\n",
      "Africa/Nouakchott\n",
      "Africa/Ouagadougou\n",
      "Africa/Porto-Novo\n",
      "Africa/Sao_Tome\n",
      "Africa/Timbuktu\n",
      "Africa/Tripoli\n",
      "Africa/Tunis\n",
      "Africa/Windhoek\n",
      "America/Adak\n",
      "America/Anchorage\n",
      "America/Anguilla\n",
      "America/Antigua\n",
      "America/Araguaina\n",
      "America/Argentina/Buenos_Aires\n",
      "America/Argentina/Catamarca\n",
      "America/Argentina/ComodRivadavia\n",
      "America/Argentina/Cordoba\n",
      "America/Argentina/Jujuy\n",
      "America/Argentina/La_Rioja\n",
      "America/Argentina/Mendoza\n",
      "America/Argentina/Rio_Gallegos\n",
      "America/Argentina/Salta\n",
      "America/Argentina/San_Juan\n",
      "America/Argentina/San_Luis\n",
      "America/Argentina/Tucuman\n",
      "America/Argentina/Ushuaia\n",
      "America/Aruba\n",
      "America/Asuncion\n",
      "America/Atikokan\n",
      "America/Atka\n",
      "America/Bahia\n",
      "America/Bahia_Banderas\n",
      "America/Barbados\n",
      "America/Belem\n",
      "America/Belize\n",
      "America/Blanc-Sablon\n",
      "America/Boa_Vista\n",
      "America/Bogota\n",
      "America/Boise\n",
      "America/Buenos_Aires\n",
      "America/Cambridge_Bay\n",
      "America/Campo_Grande\n",
      "America/Cancun\n",
      "America/Caracas\n",
      "America/Catamarca\n",
      "America/Cayenne\n",
      "America/Cayman\n",
      "America/Chicago\n",
      "America/Chihuahua\n",
      "America/Coral_Harbour\n",
      "America/Cordoba\n",
      "America/Costa_Rica\n",
      "America/Creston\n",
      "America/Cuiaba\n",
      "America/Curacao\n",
      "America/Danmarkshavn\n",
      "America/Dawson\n",
      "America/Dawson_Creek\n",
      "America/Denver\n",
      "America/Detroit\n",
      "America/Dominica\n",
      "America/Edmonton\n",
      "America/Eirunepe\n",
      "America/El_Salvador\n",
      "America/Ensenada\n",
      "America/Fort_Nelson\n",
      "America/Fort_Wayne\n",
      "America/Fortaleza\n",
      "America/Glace_Bay\n",
      "America/Godthab\n",
      "America/Goose_Bay\n",
      "America/Grand_Turk\n",
      "America/Grenada\n",
      "America/Guadeloupe\n",
      "America/Guatemala\n",
      "America/Guayaquil\n",
      "America/Guyana\n",
      "America/Halifax\n",
      "America/Havana\n",
      "America/Hermosillo\n",
      "America/Indiana/Indianapolis\n",
      "America/Indiana/Knox\n",
      "America/Indiana/Marengo\n",
      "America/Indiana/Petersburg\n",
      "America/Indiana/Tell_City\n",
      "America/Indiana/Vevay\n",
      "America/Indiana/Vincennes\n",
      "America/Indiana/Winamac\n",
      "America/Indianapolis\n",
      "America/Inuvik\n",
      "America/Iqaluit\n",
      "America/Jamaica\n",
      "America/Jujuy\n",
      "America/Juneau\n",
      "America/Kentucky/Louisville\n",
      "America/Kentucky/Monticello\n",
      "America/Knox_IN\n",
      "America/Kralendijk\n",
      "America/La_Paz\n",
      "America/Lima\n",
      "America/Los_Angeles\n",
      "America/Louisville\n",
      "America/Lower_Princes\n",
      "America/Maceio\n",
      "America/Managua\n",
      "America/Manaus\n",
      "America/Marigot\n",
      "America/Martinique\n",
      "America/Matamoros\n",
      "America/Mazatlan\n",
      "America/Mendoza\n",
      "America/Menominee\n",
      "America/Merida\n",
      "America/Metlakatla\n",
      "America/Mexico_City\n",
      "America/Miquelon\n",
      "America/Moncton\n",
      "America/Monterrey\n",
      "America/Montevideo\n",
      "America/Montreal\n",
      "America/Montserrat\n",
      "America/Nassau\n",
      "America/New_York\n",
      "America/Nipigon\n",
      "America/Nome\n",
      "America/Noronha\n",
      "America/North_Dakota/Beulah\n",
      "America/North_Dakota/Center\n",
      "America/North_Dakota/New_Salem\n",
      "America/Ojinaga\n",
      "America/Panama\n",
      "America/Pangnirtung\n",
      "America/Paramaribo\n",
      "America/Phoenix\n",
      "America/Port-au-Prince\n",
      "America/Port_of_Spain\n",
      "America/Porto_Acre\n",
      "America/Porto_Velho\n",
      "America/Puerto_Rico\n",
      "America/Punta_Arenas\n",
      "America/Rainy_River\n",
      "America/Rankin_Inlet\n",
      "America/Recife\n",
      "America/Regina\n",
      "America/Resolute\n",
      "America/Rio_Branco\n",
      "America/Rosario\n",
      "America/Santa_Isabel\n",
      "America/Santarem\n",
      "America/Santiago\n",
      "America/Santo_Domingo\n",
      "America/Sao_Paulo\n",
      "America/Scoresbysund\n",
      "America/Shiprock\n",
      "America/Sitka\n",
      "America/St_Barthelemy\n",
      "America/St_Johns\n",
      "America/St_Kitts\n",
      "America/St_Lucia\n",
      "America/St_Thomas\n",
      "America/St_Vincent\n",
      "America/Swift_Current\n",
      "America/Tegucigalpa\n",
      "America/Thule\n",
      "America/Thunder_Bay\n",
      "America/Tijuana\n",
      "America/Toronto\n",
      "America/Tortola\n",
      "America/Vancouver\n",
      "America/Virgin\n",
      "America/Whitehorse\n",
      "America/Winnipeg\n",
      "America/Yakutat\n",
      "America/Yellowknife\n",
      "Antarctica/Casey\n",
      "Antarctica/Davis\n",
      "Antarctica/DumontDUrville\n",
      "Antarctica/Macquarie\n",
      "Antarctica/Mawson\n",
      "Antarctica/McMurdo\n",
      "Antarctica/Palmer\n",
      "Antarctica/Rothera\n",
      "Antarctica/South_Pole\n",
      "Antarctica/Syowa\n",
      "Antarctica/Troll\n",
      "Antarctica/Vostok\n",
      "Arctic/Longyearbyen\n",
      "Asia/Aden\n",
      "Asia/Almaty\n",
      "Asia/Amman\n",
      "Asia/Anadyr\n",
      "Asia/Aqtau\n",
      "Asia/Aqtobe\n",
      "Asia/Ashgabat\n",
      "Asia/Ashkhabad\n",
      "Asia/Atyrau\n",
      "Asia/Baghdad\n",
      "Asia/Bahrain\n",
      "Asia/Baku\n",
      "Asia/Bangkok\n",
      "Asia/Barnaul\n",
      "Asia/Beirut\n",
      "Asia/Bishkek\n",
      "Asia/Brunei\n",
      "Asia/Calcutta\n",
      "Asia/Chita\n",
      "Asia/Choibalsan\n",
      "Asia/Chongqing\n",
      "Asia/Chungking\n",
      "Asia/Colombo\n",
      "Asia/Dacca\n",
      "Asia/Damascus\n",
      "Asia/Dhaka\n",
      "Asia/Dili\n",
      "Asia/Dubai\n",
      "Asia/Dushanbe\n",
      "Asia/Famagusta\n",
      "Asia/Gaza\n",
      "Asia/Harbin\n",
      "Asia/Hebron\n",
      "Asia/Ho_Chi_Minh\n",
      "Asia/Hong_Kong\n",
      "Asia/Hovd\n",
      "Asia/Irkutsk\n",
      "Asia/Istanbul\n",
      "Asia/Jakarta\n",
      "Asia/Jayapura\n",
      "Asia/Jerusalem\n",
      "Asia/Kabul\n",
      "Asia/Kamchatka\n",
      "Asia/Karachi\n",
      "Asia/Kashgar\n",
      "Asia/Kathmandu\n",
      "Asia/Katmandu\n",
      "Asia/Khandyga\n",
      "Asia/Kolkata\n",
      "Asia/Krasnoyarsk\n",
      "Asia/Kuala_Lumpur\n",
      "Asia/Kuching\n",
      "Asia/Kuwait\n",
      "Asia/Macao\n",
      "Asia/Macau\n",
      "Asia/Magadan\n",
      "Asia/Makassar\n",
      "Asia/Manila\n",
      "Asia/Muscat\n",
      "Asia/Nicosia\n",
      "Asia/Novokuznetsk\n",
      "Asia/Novosibirsk\n",
      "Asia/Omsk\n",
      "Asia/Oral\n",
      "Asia/Phnom_Penh\n",
      "Asia/Pontianak\n",
      "Asia/Pyongyang\n",
      "Asia/Qatar\n",
      "Asia/Qyzylorda\n",
      "Asia/Rangoon\n",
      "Asia/Riyadh\n",
      "Asia/Saigon\n",
      "Asia/Sakhalin\n",
      "Asia/Samarkand\n",
      "Asia/Seoul\n",
      "Asia/Shanghai\n",
      "Asia/Singapore\n",
      "Asia/Srednekolymsk\n",
      "Asia/Taipei\n",
      "Asia/Tashkent\n",
      "Asia/Tbilisi\n",
      "Asia/Tehran\n",
      "Asia/Tel_Aviv\n",
      "Asia/Thimbu\n",
      "Asia/Thimphu\n",
      "Asia/Tokyo\n",
      "Asia/Tomsk\n",
      "Asia/Ujung_Pandang\n",
      "Asia/Ulaanbaatar\n",
      "Asia/Ulan_Bator\n",
      "Asia/Urumqi\n",
      "Asia/Ust-Nera\n",
      "Asia/Vientiane\n",
      "Asia/Vladivostok\n",
      "Asia/Yakutsk\n",
      "Asia/Yangon\n",
      "Asia/Yekaterinburg\n",
      "Asia/Yerevan\n",
      "Atlantic/Azores\n",
      "Atlantic/Bermuda\n",
      "Atlantic/Canary\n",
      "Atlantic/Cape_Verde\n",
      "Atlantic/Faeroe\n",
      "Atlantic/Faroe\n",
      "Atlantic/Jan_Mayen\n",
      "Atlantic/Madeira\n",
      "Atlantic/Reykjavik\n",
      "Atlantic/South_Georgia\n",
      "Atlantic/St_Helena\n",
      "Atlantic/Stanley\n",
      "Australia/ACT\n",
      "Australia/Adelaide\n",
      "Australia/Brisbane\n",
      "Australia/Broken_Hill\n",
      "Australia/Canberra\n",
      "Australia/Currie\n",
      "Australia/Darwin\n",
      "Australia/Eucla\n",
      "Australia/Hobart\n",
      "Australia/LHI\n",
      "Australia/Lindeman\n",
      "Australia/Lord_Howe\n",
      "Australia/Melbourne\n",
      "Australia/NSW\n",
      "Australia/North\n",
      "Australia/Perth\n",
      "Australia/Queensland\n",
      "Australia/South\n",
      "Australia/Sydney\n",
      "Australia/Tasmania\n",
      "Australia/Victoria\n",
      "Australia/West\n",
      "Australia/Yancowinna\n",
      "Brazil/Acre\n",
      "Brazil/DeNoronha\n",
      "Brazil/East\n",
      "Brazil/West\n",
      "CET\n",
      "CST6CDT\n",
      "Canada/Atlantic\n",
      "Canada/Central\n",
      "Canada/Eastern\n",
      "Canada/Mountain\n",
      "Canada/Newfoundland\n",
      "Canada/Pacific\n",
      "Canada/Saskatchewan\n",
      "Canada/Yukon\n",
      "Chile/Continental\n",
      "Chile/EasterIsland\n",
      "Cuba\n",
      "EET\n",
      "EST\n",
      "EST5EDT\n",
      "Egypt\n",
      "Eire\n",
      "Etc/GMT\n",
      "Etc/GMT+0\n",
      "Etc/GMT+1\n",
      "Etc/GMT+10\n",
      "Etc/GMT+11\n",
      "Etc/GMT+12\n",
      "Etc/GMT+2\n",
      "Etc/GMT+3\n",
      "Etc/GMT+4\n",
      "Etc/GMT+5\n",
      "Etc/GMT+6\n",
      "Etc/GMT+7\n",
      "Etc/GMT+8\n",
      "Etc/GMT+9\n",
      "Etc/GMT-0\n",
      "Etc/GMT-1\n",
      "Etc/GMT-10\n",
      "Etc/GMT-11\n",
      "Etc/GMT-12\n",
      "Etc/GMT-13\n",
      "Etc/GMT-14\n",
      "Etc/GMT-2\n",
      "Etc/GMT-3\n",
      "Etc/GMT-4\n",
      "Etc/GMT-5\n",
      "Etc/GMT-6\n",
      "Etc/GMT-7\n",
      "Etc/GMT-8\n",
      "Etc/GMT-9\n",
      "Etc/GMT0\n",
      "Etc/Greenwich\n",
      "Etc/UCT\n",
      "Etc/UTC\n",
      "Etc/Universal\n",
      "Etc/Zulu\n",
      "Europe/Amsterdam\n",
      "Europe/Andorra\n",
      "Europe/Astrakhan\n",
      "Europe/Athens\n",
      "Europe/Belfast\n",
      "Europe/Belgrade\n",
      "Europe/Berlin\n",
      "Europe/Bratislava\n",
      "Europe/Brussels\n",
      "Europe/Bucharest\n",
      "Europe/Budapest\n",
      "Europe/Busingen\n",
      "Europe/Chisinau\n",
      "Europe/Copenhagen\n",
      "Europe/Dublin\n",
      "Europe/Gibraltar\n",
      "Europe/Guernsey\n",
      "Europe/Helsinki\n",
      "Europe/Isle_of_Man\n",
      "Europe/Istanbul\n",
      "Europe/Jersey\n",
      "Europe/Kaliningrad\n",
      "Europe/Kiev\n",
      "Europe/Kirov\n",
      "Europe/Lisbon\n",
      "Europe/Ljubljana\n",
      "Europe/London\n",
      "Europe/Luxembourg\n",
      "Europe/Madrid\n",
      "Europe/Malta\n",
      "Europe/Mariehamn\n",
      "Europe/Minsk\n",
      "Europe/Monaco\n",
      "Europe/Moscow\n",
      "Europe/Nicosia\n",
      "Europe/Oslo\n",
      "Europe/Paris\n",
      "Europe/Podgorica\n",
      "Europe/Prague\n",
      "Europe/Riga\n",
      "Europe/Rome\n",
      "Europe/Samara\n",
      "Europe/San_Marino\n",
      "Europe/Sarajevo\n",
      "Europe/Saratov\n",
      "Europe/Simferopol\n",
      "Europe/Skopje\n",
      "Europe/Sofia\n",
      "Europe/Stockholm\n",
      "Europe/Tallinn\n",
      "Europe/Tirane\n",
      "Europe/Tiraspol\n",
      "Europe/Ulyanovsk\n",
      "Europe/Uzhgorod\n",
      "Europe/Vaduz\n",
      "Europe/Vatican\n",
      "Europe/Vienna\n",
      "Europe/Vilnius\n",
      "Europe/Volgograd\n",
      "Europe/Warsaw\n",
      "Europe/Zagreb\n",
      "Europe/Zaporozhye\n",
      "Europe/Zurich\n",
      "GB\n",
      "GB-Eire\n",
      "GMT\n",
      "GMT+0\n",
      "GMT-0\n",
      "GMT0\n",
      "Greenwich\n",
      "HST\n",
      "Hongkong\n",
      "Iceland\n",
      "Indian/Antananarivo\n",
      "Indian/Chagos\n",
      "Indian/Christmas\n",
      "Indian/Cocos\n",
      "Indian/Comoro\n",
      "Indian/Kerguelen\n",
      "Indian/Mahe\n",
      "Indian/Maldives\n",
      "Indian/Mauritius\n",
      "Indian/Mayotte\n",
      "Indian/Reunion\n",
      "Iran\n",
      "Israel\n",
      "Jamaica\n",
      "Japan\n",
      "Kwajalein\n",
      "Libya\n",
      "MET\n",
      "MST\n",
      "MST7MDT\n",
      "Mexico/BajaNorte\n",
      "Mexico/BajaSur\n",
      "Mexico/General\n",
      "NZ\n",
      "NZ-CHAT\n",
      "Navajo\n",
      "PRC\n",
      "PST8PDT\n",
      "Pacific/Apia\n",
      "Pacific/Auckland\n",
      "Pacific/Bougainville\n",
      "Pacific/Chatham\n",
      "Pacific/Chuuk\n",
      "Pacific/Easter\n",
      "Pacific/Efate\n",
      "Pacific/Enderbury\n",
      "Pacific/Fakaofo\n",
      "Pacific/Fiji\n",
      "Pacific/Funafuti\n",
      "Pacific/Galapagos\n",
      "Pacific/Gambier\n",
      "Pacific/Guadalcanal\n",
      "Pacific/Guam\n",
      "Pacific/Honolulu\n",
      "Pacific/Johnston\n",
      "Pacific/Kiritimati\n",
      "Pacific/Kosrae\n",
      "Pacific/Kwajalein\n",
      "Pacific/Majuro\n",
      "Pacific/Marquesas\n",
      "Pacific/Midway\n",
      "Pacific/Nauru\n",
      "Pacific/Niue\n",
      "Pacific/Norfolk\n",
      "Pacific/Noumea\n",
      "Pacific/Pago_Pago\n",
      "Pacific/Palau\n",
      "Pacific/Pitcairn\n",
      "Pacific/Pohnpei\n",
      "Pacific/Ponape\n",
      "Pacific/Port_Moresby\n",
      "Pacific/Rarotonga\n",
      "Pacific/Saipan\n",
      "Pacific/Samoa\n",
      "Pacific/Tahiti\n",
      "Pacific/Tarawa\n",
      "Pacific/Tongatapu\n",
      "Pacific/Truk\n",
      "Pacific/Wake\n",
      "Pacific/Wallis\n",
      "Pacific/Yap\n",
      "Poland\n",
      "Portugal\n",
      "ROC\n",
      "ROK\n",
      "Singapore\n",
      "Turkey\n",
      "UCT\n",
      "US/Alaska\n",
      "US/Aleutian\n",
      "US/Arizona\n",
      "US/Central\n",
      "US/East-Indiana\n",
      "US/Eastern\n",
      "US/Hawaii\n",
      "US/Indiana-Starke\n",
      "US/Michigan\n",
      "US/Mountain\n",
      "US/Pacific\n",
      "US/Samoa\n",
      "UTC\n",
      "Universal\n",
      "W-SU\n",
      "WET\n",
      "Zulu\n"
     ]
    }
   ],
   "source": [
    "for tz in pytz.all_timezones:\n",
    "    print(tz)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example, Berlin is GMT+1 (flip the sign):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 246,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-03-06 00:00:00+01:00', '2012-03-07 00:00:00+01:00',\n",
       "               '2012-03-08 00:00:00+01:00', '2012-03-09 00:00:00+01:00',\n",
       "               '2012-03-10 00:00:00+01:00', '2012-03-11 00:00:00+01:00',\n",
       "               '2012-03-12 00:00:00+01:00', '2012-03-13 00:00:00+01:00',\n",
       "               '2012-03-14 00:00:00+01:00', '2012-03-15 00:00:00+01:00',\n",
       "               '2012-03-16 00:00:00+01:00', '2012-03-17 00:00:00+01:00',\n",
       "               '2012-03-18 00:00:00+01:00', '2012-03-19 00:00:00+01:00',\n",
       "               '2012-03-20 00:00:00+01:00'],\n",
       "              dtype='datetime64[ns, Europe/Berlin]', freq='D')"
      ]
     },
     "execution_count": 246,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng.tz_localize('Europe/Berlin')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 247,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-03-06 00:00:00+01:00', '2012-03-07 00:00:00+01:00',\n",
       "               '2012-03-08 00:00:00+01:00', '2012-03-09 00:00:00+01:00',\n",
       "               '2012-03-10 00:00:00+01:00', '2012-03-11 00:00:00+01:00',\n",
       "               '2012-03-12 00:00:00+01:00', '2012-03-13 00:00:00+01:00',\n",
       "               '2012-03-14 00:00:00+01:00', '2012-03-15 00:00:00+01:00',\n",
       "               '2012-03-16 00:00:00+01:00', '2012-03-17 00:00:00+01:00',\n",
       "               '2012-03-18 00:00:00+01:00', '2012-03-19 00:00:00+01:00',\n",
       "               '2012-03-20 00:00:00+01:00'],\n",
       "              dtype='datetime64[ns, Etc/GMT-1]', freq='D')"
      ]
     },
     "execution_count": 247,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng.tz_localize('Etc/GMT-1')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can check timezones by converting the current time 'now' to another time zone:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 248,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-11-19 13:25:58.653812')"
      ]
     },
     "execution_count": 248,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('now')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 249,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-11-19 16:25:58.667135-0500', tz='US/Eastern')"
      ]
     },
     "execution_count": 249,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('now', tz='US/Eastern')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 250,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-11-19 21:25:58.679224+0000', tz='UTC')"
      ]
     },
     "execution_count": 250,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('now', tz='UTC')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 251,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-11-20 00:25:58.688456+0300', tz='Asia/Riyadh')"
      ]
     },
     "execution_count": 251,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('now', tz='Asia/Riyadh')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 252,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Timestamp('2018-11-20 00:25:58.699743+0300', tz='Etc/GMT-3')"
      ]
     },
     "execution_count": 252,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Timestamp('now', tz='Etc/GMT-3')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### Example: Day of week corresponding to a future date"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 253,
   "metadata": {},
   "outputs": [],
   "source": [
    "def future_day_of_week(date, years_offset):\n",
    "    # dictionary to rename day of week\n",
    "    day_dict = {0: 'Monday', 1: 'Tuesday', 2: 'Wednesday', 3: 'Thursday', \n",
    "                4: 'Friday', 5: 'Saturday', 6: 'Sunday'}\n",
    "    # covert date to timestamp\n",
    "    ts = pd.Timestamp(date)\n",
    "    # offset date by X years\n",
    "    ts_offset = ts + pd.tseries.offsets.DateOffset(years=years_offset)\n",
    "    # print with strftime to make date pretty\n",
    "    print('%s in %s years will be %s which is a %s.' % (\n",
    "            ts.strftime('%Y-%m-%d'), \n",
    "            years_offset, \n",
    "            ts_offset.strftime('%Y-%m-%d'), \n",
    "            day_dict[ts_offset.dayofweek]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 254,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2000-01-01 in 21 years will be 2021-01-01 which is a Friday.\n"
     ]
    }
   ],
   "source": [
    "future_day_of_week('1/1/00', 21)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 255,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "36"
      ]
     },
     "execution_count": 255,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# days from today until a given day\n",
    "pd.Period('12/25/18', 'D') - pd.Period(pd.datetime.today(), 'D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
